diff --git a/CHANGELOG.md b/CHANGELOG.md index d6868dceff..85d58666fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ - [#4579](https://github.com/blockscout/blockscout/pull/4579) - Write contract page: Resize inputs; Improve multiplier selector ### Fixes +- [#4764](https://github.com/blockscout/blockscout/pull/4764) - Add cleaning of substrings of `require` messages from parsed constructor arguments - [#4751](https://github.com/blockscout/blockscout/pull/4751) - Change text and link for `trade STAKE` button - [#4746](https://github.com/blockscout/blockscout/pull/4746) - Fix comparison of decimal value - [#4711](https://github.com/blockscout/blockscout/pull/4711) - Add trimming to the contract functions inputs diff --git a/apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex b/apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex index 5126e4b280..15f4c89d43 100644 --- a/apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex +++ b/apps/explorer/lib/explorer/smart_contract/verifier/constructor_arguments.ex @@ -220,6 +220,7 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do ) <<>> -> + # we should consdider change: use just :false check_func.("") <<_::binary-size(2)>> <> rest -> @@ -278,10 +279,46 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do if check_func_result do check_func_result else - extract_constructor_arguments(filtered_constructor_arguments, check_func, contract_source_code, contract_name) + output = + extract_constructor_arguments(filtered_constructor_arguments, check_func, contract_source_code, contract_name) + + if output do + output + else + # https://github.com/blockscout/blockscout/pull/4764 + clean_constructor_arguments = + remove_substring_of_require_messages(filtered_constructor_arguments, contract_source_code, contract_name) + + check_func.(clean_constructor_arguments) + end end end + defp remove_substring_of_require_messages(constructor_arguments, contract_source_code, contract_name) do + require_msgs = + contract_source_code + |> extract_require_messages_from_constructor(contract_name) + |> Enum.filter(fn require_msg -> require_msg != nil end) + + longest_substring_to_delete = + Enum.reduce(require_msgs, "", fn msg, best_match -> + case String.myers_difference(constructor_arguments, msg) do + [{:eq, match} | _] -> + if String.length(match) > String.length(best_match) do + match + else + best_match + end + + _ -> + best_match + end + end) + + [_, cleaned_constructor_arguments] = String.split(constructor_arguments, longest_substring_to_delete, parts: 2) + cleaned_constructor_arguments + end + def remove_require_messages_from_constructor_arguments(contract_source_code, constructor_arguments, contract_name) do all_msgs = contract_source_code @@ -345,7 +382,8 @@ defmodule Explorer.SmartContract.Verifier.ConstructorArguments do assumed_arguments rescue - _ -> false + _ -> + false end end