From d4391d883a552cb8db59f78a65f295b0ee753fd3 Mon Sep 17 00:00:00 2001 From: Jan Hnatek Date: Thu, 5 Sep 2024 11:47:10 +0200 Subject: [PATCH] fix(core): add EIP-712 nested arrays support (#2963) --- .../fixtures/ethereum/sign_typed_data.json | 80 +++++++++++++++++++ core/.changelog.d/2963.fixed | 1 + core/src/apps/ethereum/sign_typed_data.py | 12 ++- python/src/trezorlib/ethereum.py | 3 - 4 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 core/.changelog.d/2963.fixed diff --git a/common/tests/fixtures/ethereum/sign_typed_data.json b/common/tests/fixtures/ethereum/sign_typed_data.json index 35b484a160..7ac80d9222 100644 --- a/common/tests/fixtures/ethereum/sign_typed_data.json +++ b/common/tests/fixtures/ethereum/sign_typed_data.json @@ -757,6 +757,86 @@ "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", "sig": "0x4873bf73cf22e35776d8b23a249f93f38a6d5aa8c1a121281675094f5fac64b55a3b6cf28e140930f9185156d07f171a17e06925b5cebd95a2a8761d074e43f91c" } + }, + { + "name": "nested_array_of_string", + "comment": "Nested arrays (issue #2963)", + "parameters": { + "path": "m/44'/60'/0'/0/0", + "metamask_v4_compat": true, + "data": { + "types": { + "EIP712Domain": [], + "Message": [ + { + "name": "text", + "type": "string[][]" + } + ] + }, + "primaryType": "Message", + "message": { + "text": [ + ["1", "2"], + ["3", "4"] + ] + }, + "domain": {} + }, + "message_hash": "0xc40dc798242ec8a6a0f2974e8f687583c118a6b74f161dc39cd79025d228ca1d", + "domain_separator_hash": null + }, + "result": { + "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", + "sig": "0x26df1807221e9a0ce4d3f0a6422c55f9cca7de55268a9d6c4772fd28893730b8755f3d23cef14ea02ea74c9045a3a8ae6a3f1ceb252cd2a6f3a43832d8a0c7b01c" + } + }, + { + "name": "nested_array_of_object", + "comment": "Nested arrays (issue #2963)", + "parameters": { + "path": "m/44'/60'/0'/0/0", + "metamask_v4_compat": true, + "data": { + "types": { + "EIP712Domain": [], + "Message": [ + { + "name": "element", + "type": "Element[][]" + } + ], + "Element": [ + { + "name": "foo", + "type": "int8" + } + ] + }, + "primaryType": "Message", + "message": { + "element": [ + [ + { + "foo": 1 + } + ], + [ + { + "foo": 2 + } + ] + ] + }, + "domain": {} + }, + "message_hash": "0x56034f4b5afe2fb032f1e60b3bc649c8725396d1e9b4d85725bdff1d366a86e6", + "domain_separator_hash": null + }, + "result": { + "address": "0x73d0385F4d8E00C5e6504C6030F47BF6212736A8", + "sig": "0x6f2c2e2392ca20374679b4d34a2e910cf2357c32ce06c25592c1ebe5a77e76433e4b38d853ccce71930df085861a90c36611a24ba673964bf6a889a063c568311b" + } } ] } diff --git a/core/.changelog.d/2963.fixed b/core/.changelog.d/2963.fixed new file mode 100644 index 0000000000..2d2a691f97 --- /dev/null +++ b/core/.changelog.d/2963.fixed @@ -0,0 +1 @@ +Fixed EIP-712 nested arrays support. diff --git a/core/src/apps/ethereum/sign_typed_data.py b/core/src/apps/ethereum/sign_typed_data.py index 4fc2f0c095..848466f92d 100644 --- a/core/src/apps/ethereum/sign_typed_data.py +++ b/core/src/apps/ethereum/sign_typed_data.py @@ -374,7 +374,6 @@ class TypedDataEnvelope: for i in range(array_size): field_member_path[-1] = i - # TODO: we do not support arrays of arrays, check if we should if entry_type.data_type == EthereumDataType.STRUCT: assert entry_type.struct_name is not None # validate_field_type @@ -387,6 +386,17 @@ class TypedDataEnvelope: is_array_member=True, ) + elif entry_type.data_type == EthereumDataType.ARRAY: + await self.encode_array( + arr_w, + array_name, + entry_type, + field_member_path, + show_array, + parent_objects, + current_parent_objects, + ) + else: await self.encode_nonref( arr_w, diff --git a/python/src/trezorlib/ethereum.py b/python/src/trezorlib/ethereum.py index 1cf2eeeaed..1be8983228 100644 --- a/python/src/trezorlib/ethereum.py +++ b/python/src/trezorlib/ethereum.py @@ -87,9 +87,6 @@ def get_field_type(type_name: str, types: dict) -> messages.EthereumFieldType: size = parse_array_n(type_name) member_typename = typeof_array(type_name) entry_type = get_field_type(member_typename, types) - # Not supporting nested arrays currently - if entry_type.data_type == messages.EthereumDataType.ARRAY: - raise NotImplementedError("Nested arrays are not supported") elif type_name.startswith("uint"): data_type = messages.EthereumDataType.UINT size = get_byte_size_for_int_type(type_name)