Skip to content

Commit

Permalink
Fix Dynamic Tuple Encoding
Browse files Browse the repository at this point in the history
This patch had a bug that new tuple arg types (`%{type: type, name: ...}`) were beign interpreted as "not dynamic" in the `is_dynamic?` code since we had a catch-all that wasn't clear it was incorrectly matching the inner value. We both a) fix the matching, and b) are explicit about declaring this function for all types so we don't silently get it wrong in the future.

Bump to 1.0.0-alpha5
  • Loading branch information
hayesgm committed Feb 9, 2024
1 parent 57e2557 commit 59e9b18
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ by adding `abi` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:abi, "~> 1.0.0-alpha4"}
{:abi, "~> 1.0.0-alpha5"}
]
end
```
Expand Down
8 changes: 5 additions & 3 deletions lib/abi/function_selector.ex
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,11 @@ defmodule ABI.FunctionSelector do
def is_dynamic?(:string), do: true
def is_dynamic?({:array, _type}), do: true
def is_dynamic?({:array, type, len}) when len > 0, do: is_dynamic?(type)
def is_dynamic?({:tuple, types}), do: Enum.any?(types, &is_dynamic?/1)
def is_dynamic?({:struct, _name, types, _names}), do: Enum.any?(types, &is_dynamic?/1)
def is_dynamic?(_), do: false
def is_dynamic?({:tuple, types}), do: Enum.any?(types, fn arg_type -> is_dynamic?(arg_type.type) end)
def is_dynamic?({:bytes,_}), do: false
def is_dynamic?({:uint,_}), do: false
def is_dynamic?(:bool), do: false
def is_dynamic?(:address), do: false

@doc false
@spec get_function_type(String.t()) :: function_type()
Expand Down
46 changes: 46 additions & 0 deletions lib/abi/type_encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,52 @@ defmodule ABI.TypeEncoder do
...> )
...> |> Base.encode16(case: :lower)
"000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000000000000000001"
iex> [
...> <<1::160>>,
...> <<2::160>>,
...> <<3::256>>,
...> {
...> 4,
...> <<5::160>>,
...> <<6>>,
...> <<7::512>>,
...> 8
...> },
...> 9,
...> <<0xa::256>>,
...> <<0xb::256>>
...> ]
...> |> ABI.TypeEncoder.encode(
...> %ABI.FunctionSelector{
...> function: "test",
...> function_type: :function,
...> state_mutability: :nonpayable,
...> types: [
...> %{name: "a", type: :address},
...> %{name: "b", type: :address},
...> %{name: "c", type: {:bytes, 32}},
...> %{
...> name: "d",
...> type:
...> {:tuple,
...> [
...> %{name: "e", type: {:uint, 96}},
...> %{name: "f", type: :address},
...> %{name: "g", type: :bytes},
...> %{name: "h", type: :bytes},
...> %{name: "i", type: {:uint, 256}}
...> ]}
...> },
...> %{name: "j", type: {:uint, 8}},
...> %{name: "k", type: {:bytes, 32}},
...> %{name: "l", type: {:bytes, 32}}
...> ],
...> returns: [%{name: "", type: :bytes}]
...> }
...> )
...> |> Base.encode16(case: :lower)
"19c9d90a00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000010600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007"
"""
def encode(data, function_selector) do
encode_method_id(function_selector) <> do_encode_data(data, function_selector)
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ defmodule ABI.Mixfile do
def project do
[
app: :abi,
version: "1.0.0-alpha4",
version: "1.0.0-alpha5",
elixir: "~> 1.14",
description: "Ethereum's ABI Interface",
package: [
Expand Down

0 comments on commit 59e9b18

Please sign in to comment.