test(7.15): ERC-7730 formatter mirror and runtime evidence (block 7b) - #228
Open
BitHighlander wants to merge 15 commits into
Open
BitHighlander wants to merge 15 commits into
BitHighlander wants to merge 15 commits into
Conversation
…ants Phase A of the ERC-7730 formatter plan. The device now executes tokenAmount (value, token, threshold, message, native aliases), addressName, @.from/@.to (calldata only) and signed constants, and type-checks every argument at preload. Mirror that table, including the value classes: amount and threshold are integers, token and addressName values are addresses, raw literals are integers, addresses or strings, and an alias set names at most four addresses. The registry test now asserts 812 signable formats (from 92). The device still refuses addressName and tokenAmount over bytes32/uint256 words that pack an address or an encrypted amount.
Phase B. The device executes display opcodes 2 and 3 as one run directly after the plain intent, showing each fragment and value as a numbered part. Mirror the opcodes and the run rule, and trim fragment edges: each part is its own screen, and the device escapes edge spaces. The registry test now asserts 954 signable formats.
Phase C. Mirror the device's new formatters and their argument classes: a date encoding must be the string "timestamp" or "blockheight", unit decimals a one-byte literal and the prefix a flag, an enum map at most 16 entries, an NFT collection an address, and @.value an unsigned value. The registry test now asserts 1,138 signable formats.
…elds Phase D. Mirror the device: display opcodes 5-8, the "every element" path step reached through tuples only, iteration over one array at a time in calldata definitions, every field inside it reading that array, and only the "optional" condition (always shown). A path ending in its every-element step is also a value when its element is a leaf (address[] recipients). The registry test now asserts 1,294 signable formats.
Phase E1. Emit amountPath and spenderPath as formatter roles 17 and 18 beside the callee (15), and mirror the device: embedded calldata executes for calldata definitions, shown under a blind-sign warning in 7.15. The registry test now asserts 1,326 signable formats.
Phase E2. When the device asks for an embedded call's definition (recursion_depth >= 1) and the catalog holds none, reply with the empty chunk (offset 0, total_length 0, no data) instead of failing: firmware 7.15 then shows the inner call under a blind-sign warning, and 7.16 rejects it. A top-level lookup that fails is still an error.
The compiler's device-capability mirror now refuses what the firmware verifier refuses after the 7b audit: - signer text (labels, threshold messages, unit bases, enum labels) over 64 bytes, and unit decimals over 77; - an embedded call's callee given as a literal, and an embedded call used as an intent value part; - tables beyond the device's limits (alias sets, enum maps). Numeric constants are values of every width, as on the device. The string table is parsed before the literals that reference it. The registry lockstep test still asserts 1,326 signable formats; its comment now says what the count means: preload-accepted, not "runs end to end".
The Phase 0-E ERC-7730 runtime wire tests move here from keepkey-firmware's scripts/emulator/test_stack07_regressions.py. Only python-keepkey tests get OLED captures in the release PDF. Firmware keeps its 7a contracts and imports Erc7730Harness from this module. tests/test_msg_ethereum_erc7730_runtime.py (34 tests, full product, 7.15.0+): - every test that signs first signs the same transaction on the ordinary path and requires an identical signature; - the showcased walk runs last, because only its frames are kept; - the ordinary review that follows is not captured: it is unchanged, and the report's frame picker would otherwise prefer its per-transaction data hash over the certified screens; - new: a call at depth two is shown blind, and the device requests no definition deeper than depth one; - test_inner_containers_and_depth_two is renamed test_inner_calls_read_their_own_containers: it has no depth-2 call. generate-test-report.py: - new section EX (7.15.0): what the device executes, where each fact comes from, the 7.15 blind-sign rule for embedded calls (7.16 rejects), and the known fail-closed limits; - rows EX1-EX34 with the OLED screens each test must capture; - four full-sequence flows; - the module is must-run from 7.15.0 on the full product. The existing ER section (7.19.0) is unchanged.
… tests Mirror (device_refusal), in step with the firmware verifier: - an enum's value must come from the signed data, never a constant; - an interpolated-intent value part may not show a signer constant; - the bindings table (section 8) is bounded at 64 like the others. The registry still has 1,326 signable formats. Runtime tests: - _certified now also requires that the device asked for the definition, so a walk that silently took the ordinary path cannot pass; - a Wanchain transaction (tx_type) is refused on the certified path before any screen (EX35); - the containers test distinguishes the outer spenderPath from the default authority. Report: EX26 no longer claims an address stays on one OLED page.
The device now shows a mapped enum value as "label (value)" followed by "label set by signer", like a unit's base. The runtime test and report row EX13 expect it.
Re-audit round 3: - No calldata test declined an ERC-7730 screen. The new test declines each of these and requires ActionCancelled and no final sign screen: a blind-sign warning (a value too long to capture, no inner definition, a refused inner definition), the second part of a split value, and an inner field. It is report row EX36. It fails when the long-value warning ignores a decline. - The parallel-arrays test now checks each element's amount as well as its token. _walk can decline by confirmation title (cancel_title).
…tests
Re-audit round 4 and its completeness critic:
- Only a raw field may show a signer constant. A constant formatted
as an amount, date, unit, enum, NFT or address looks decoded, so the
mirror refuses it, as it refuses a constant embedded value or
authority (callee already). The value classes return to what they
were before D1. The official registry uses no such constant: 1,326
formats remain signable.
- Lockstep gaps that predate this block, found by the re-audit:
- fixed ABI arrays over 64 elements are refused;
- program strings must be printable text;
- signed enum keys use minimal two's complement (-128 is 0x80), so
the device no longer refuses them.
Each is tested through the mirror and the firmware validator
together, and fails when reverted.
Runtime tests:
- test_only_a_raw_field_shows_a_signer_constant replaces
test_numeric_constants_are_values;
- a long typed-data value points to the walk, with no blind warning
(EX37);
- a refused inner definition streamed over several chunks;
- two embedded calls where the first is refused and the second is
still clear-signed (EX38);
- unit and enum marks now come before the value.
This was referenced Sep 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #227. Mirrors firmware block 7b (BitHighlander/keepkey-firmware, Phase A of the ERC-7730 formatter plan).
DEVICE_CAPABILITIESnow includes tokenAmount, addressName, the@.from/@.tocontainers (calldata only) and literal paths.