Skip to content

Commit

Permalink
Fix parsing of fixed tuple arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
ayrat555 committed Dec 9, 2020
1 parent 6ffcd54 commit 0b4aee7
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
14 changes: 14 additions & 0 deletions lib/abi/function_selector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,20 @@ defmodule ABI.FunctionSelector do
{:array, {:tuple, sub_types}}
end

def parse_specification_type(%{
"type" => "tuple[" <> tail,
"components" => components
}) do
sub_types = for component <- components, do: parse_specification_type(component)

size =
tail
|> String.replace("]", "")
|> String.to_integer()

{:array, {:tuple, sub_types}, size}
end

def parse_specification_type(%{"type" => type}), do: decode_type(type)

@doc """
Expand Down
132 changes: 132 additions & 0 deletions test/abi/function_selector_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,138 @@ defmodule ABI.FunctionSelectorTest do

assert expected_type == selector.returns
end

test "parses fixed array of tuples" do
function = %{
"constant" => false,
"inputs" => [
%{"internalType" => "uint160", "name" => "exitId", "type" => "uint160"},
%{
"components" => [
%{"internalType" => "bool", "name" => "isCanonical", "type" => "bool"},
%{
"internalType" => "uint64",
"name" => "exitStartTimestamp",
"type" => "uint64"
},
%{"internalType" => "uint256", "name" => "exitMap", "type" => "uint256"},
%{
"internalType" => "uint256",
"name" => "position",
"type" => "uint256"
},
%{
"components" => [
%{
"internalType" => "bytes32",
"name" => "outputId",
"type" => "bytes32"
},
%{
"internalType" => "address payable",
"name" => "exitTarget",
"type" => "address"
},
%{
"internalType" => "address",
"name" => "token",
"type" => "address"
},
%{
"internalType" => "uint256",
"name" => "amount",
"type" => "uint256"
},
%{
"internalType" => "uint256",
"name" => "piggybackBondSize",
"type" => "uint256"
}
],
"internalType" => "struct PaymentExitDataModel.WithdrawData[4]",
"name" => "inputs",
"type" => "tuple[4]"
},
%{
"components" => [
%{
"internalType" => "bytes32",
"name" => "outputId",
"type" => "bytes32"
},
%{
"internalType" => "address payable",
"name" => "exitTarget",
"type" => "address"
},
%{
"internalType" => "address",
"name" => "token",
"type" => "address"
},
%{
"internalType" => "uint256",
"name" => "amount",
"type" => "uint256"
},
%{
"internalType" => "uint256",
"name" => "piggybackBondSize",
"type" => "uint256"
}
],
"internalType" => "struct PaymentExitDataModel.WithdrawData[4]",
"name" => "outputs",
"type" => "tuple[4]"
},
%{
"internalType" => "address payable",
"name" => "bondOwner",
"type" => "address"
},
%{
"internalType" => "uint256",
"name" => "bondSize",
"type" => "uint256"
},
%{
"internalType" => "uint256",
"name" => "oldestCompetitorPosition",
"type" => "uint256"
}
],
"internalType" => "struct PaymentExitDataModel.InFlightExit",
"name" => "exit",
"type" => "tuple"
}
],
"name" => "setInFlightExit",
"outputs" => [],
"payable" => false,
"stateMutability" => "nonpayable",
"type" => "function"
}

expected_type = [
{:uint, 160},
{:tuple,
[
:bool,
{:uint, 64},
{:uint, 256},
{:uint, 256},
{:array, {:tuple, [{:bytes, 32}, :address, :address, {:uint, 256}, {:uint, 256}]}, 4},
{:array, {:tuple, [{:bytes, 32}, :address, :address, {:uint, 256}, {:uint, 256}]}, 4},
:address,
{:uint, 256},
{:uint, 256}
]}
]

selector = FunctionSelector.parse_specification_item(function)

assert expected_type == selector.types
end
end

describe "simple_types?/1" do
Expand Down

0 comments on commit 0b4aee7

Please sign in to comment.