diff --git a/lib/abi/function_selector.ex b/lib/abi/function_selector.ex index 04d1d5d..43a5985 100644 --- a/lib/abi/function_selector.ex +++ b/lib/abi/function_selector.ex @@ -180,7 +180,31 @@ defmodule ABI.FunctionSelector do "name" => function_name, "inputs" => named_inputs, "outputs" => named_outputs - } <- item, + } <- + item + # Workaround for ABIs that are missing the "outputs" field. + # + # For instance, consider this valid ABI: + # + # ```jsonc + # // ... + # { + # "type": "function", + # "stateMutability": "view", + # "name": "assumeLastTokenIdMatches", + # "inputs": [ + # { + # "type": "uint256", + # "name": "lastTokenId", + # "internalType": "uint256" + # } + # ] + # }, + # // ... + # ``` + # If the "outputs" field is missing, we should assume it's an empty + # list to continue parsing the ABI. + |> Map.put_new("outputs", []), true <- simple_types?(named_inputs, item), true <- simple_types?(named_outputs, item) do input_types = Enum.map(named_inputs, &parse_specification_type/1) diff --git a/test/abi/function_selector_test.exs b/test/abi/function_selector_test.exs index f0f40f2..fd43743 100644 --- a/test/abi/function_selector_test.exs +++ b/test/abi/function_selector_test.exs @@ -111,6 +111,43 @@ defmodule ABI.FunctionSelectorTest do } ] == ABI.parse_specification([abi]) end + + @doc """ + Regression test to verify the correct parsing of ABIs that lack the + "outputs" field. + """ + test "with the missing outputs field" do + abi = [ + %{ + "type" => "function", + "stateMutability" => "view", + "name" => "assumeLastTokenIdMatches", + "inputs" => [ + %{ + "type" => "uint256", + "name" => "lastTokenId", + "internalType" => "uint256" + } + ] + } + ] + + expected = [ + %FunctionSelector{ + type: :function, + function: "assumeLastTokenIdMatches", + input_names: ["lastTokenId"], + types: [uint: 256], + returns: [], + return_names: [], + method_id: <<231, 40, 120, 180>>, + inputs_indexed: nil, + state_mutability: :view + } + ] + + assert ABI.parse_specification(abi) == expected + end end describe "parse_specification_item/1" do