Repository navigation
Conversation
Adds `layout` and `dispatch` keys so ERC-7730 descriptors can describe fields whose bytes are not plain Solidity ABI - packed structs, repeated records, and tag-selected payloads - as seen in Safe MultiSend, Uniswap's Universal Router, ERC-7579 execute, Circle CCTP messages, EAS attestations, and ERC-7683 orders. Includes a `call` construct for nested/wrapped calldata (both byte-embedded and direct signature+positional-args forms) and a top-level dispatch form for calls that only exist to be redirected. Worked examples for all six real cases are full, standalone ERC-7730 descriptor files under assets/erc-non-abi-dispatch/, verified against real mined transactions rather than inlined as snippets. A seventh, made-up TieredExecutor example demonstrates the direct/positional call form, explicitly flagged in Rationale as not grounded in an observed live transaction. Co-Authored-By: Claude Sonnet 5 <[email protected]>
Adds the deterministic-deployment-proxy worked example (initCode/$fallback, verified EIP-1167 template plus a placeholder Permit2 template) and the parked stateRef-dispatch feature note, both referenced by the previous commit's spec text but left out of it.
…action) Safe's execTransaction signatures field repurposes a fixed-record field as a byte offset into a shared tail region for EIP-1271 contract signatures - the one case in this ERC's survey needing genuine pointer-style indirection within a custom-packed buffer, which object/ sequence/lengthFrom deliberately can't express. Adds the pointer layout node (bytes width, required containerPath, destination), extends the byte-width invariant and Security Considerations to cover it (including the real recursion case: a Safe signing for another Safe), and adds a worked example verified against a real nested-Safe transaction for the EOA/APPROVED_HASH paths, with the CONTRACT_SIGNATURE/pointer branch marked source-verified-only pending a live example. Co-Authored-By: Claude Sonnet 5 <[email protected]>
…on schema initCode, $fallback, and pointer are reverted: real, live code paths are not the same as evidenced usage, and none of the three cleared that bar despite genuine search effort (see prior discussion). Their example files (deterministic-deployment-proxy, safe-exectransaction) are removed, and the spec text, Rationale, Security Considerations, and Test Cases are updated accordingly. Balancer's joinPool/exitPool Test Case entry is added, since those files already existed but had no prose write-up. All example descriptors are migrated to the ERC's current vocabulary (type/object/switch/expression/format:"calldata", $default inside cases) and validate cleanly against a new, full companion JSON Schema (erc7730-non-abi-dispatch.schema.json) built as a complete schema rather than a thin extension - composing new properties onto schemas closed with additionalProperties:false, or extending a schema reached only via $ref, does not validate the way a thin allOf+$ref extension would suggest (verified empirically against real tooling, not just by reading the spec). Fixed several real bugs surfaced only by validating against actual tooling: format:"array" was never a real ERC-7730 format (the Universal Router example now uses per-element switch via $index correlation instead); uint/bitfield byte widths were wrongly restricted to powers of two in the prose, contradicting the spec's own bitfield example; the switch case-value "format" branch didn't allow params. All $comment annotations are stripped from the example files. Co-Authored-By: Claude Sonnet 5 <[email protected]>
File
|
| @@ -0,0 +1,436 @@ | |||
| --- | |||
| eip: 0000 | |||
There was a problem hiding this comment.
| eip: 0000 | |
| eip: 8362 |
Assigning next sequential EIP/ERC/RIP number.
Numbers are assigned by editors & associates.
Please also update the filename.
| title: Custom Encoding Layout for ERC-7730 | ||
| description: Format to describes any non-standard byte encodings for ERC-7730 | ||
| author: Alex Forshtat (@forshtat) | ||
| discussions-to: https://github.com/ethereum/ERCs/pull/1925 |
There was a problem hiding this comment.
Please create a discussions topic on Eth Magicians.
PrisionMike
left a comment
There was a problem hiding this comment.
I did not understand where operation is being used and what interaction is trying to achieve.
I love the overall shape of the work. I think this is what it should look like if we want to support these more packed contracts. I would want to see examples for the LiFi *packed bridge functions too.
I am concerned about the deeply nested jsons that we have, the field name mangling etc.
And the write-up could use some more elaboration and some restructuring so it reads more as an extension of ERC-7730.
I will try to use some of these examples as a bespoke parser in Trezor and see how it goes. Will reach out to @forshtat for a synchronized review/rework so we can get it moving faster.
|
|
||
| The mechanism for declaring an entry in a `sequence` data structure that is not represented by an ABI-encoded parameter. | ||
|
|
||
| It can also be used as a stand-in for any other complex data structure in the formating process. |
There was a problem hiding this comment.
This should be the default explanation. It looks odd to define something as generic as the object to be what element already does well and more specifically.
| "path": "transactions", | ||
| "customEncoding": { | ||
| "type": "sequence", | ||
| "element": { |
There was a problem hiding this comment.
element should be an attribute of customEncoding ? Any rationale?
There was a problem hiding this comment.
It just tells us that the transactions parameter IS a sequence of elements.
The customEncoding must have a type. It accepts one of: [uint, bytes, address, bool, bitfield, object, sequence, switch].
As we specified it is a sequence, it can use element.
The alternative would be a wrapper such as { "type": "sequence", "sequence": { "element": ... } }. It adds a nesting level for little gain.
Does this make sense?
| "schema": { "type": "bytes" }, | ||
| "label": "Execution", | ||
| "format": "calldata", | ||
| "params": { "calleePath": "target", "amountPath": "value" } |
There was a problem hiding this comment.
I did not plan to drop parameters in the first place - added visible back. In general we should double-check custom layouts did not drop features when merging them back to v2.2
| { | ||
| "type": "bitfield", | ||
| "bytes": 20, | ||
| "fields": [ |
There was a problem hiding this comment.
Are these fields the same as in the parent spec? A full spec using these special encoding members would mangle with the fields in the parent specifcation whose objects don't have a name field.
There was a problem hiding this comment.
Will these name attributes be used as label or would they be used in the path attribute to assign labels? The examples here seem to suggest the latter, as beforeSwap doesn't read as a label much
There was a problem hiding this comment.
Thanks, renamed fields (from the bitfied) to bitranges to avoid any trace of confusion.
So yeah, I think named fields should be used in the path attributes, but it looks like it was not fully specced out. Added text.
But, if the field is a simple value it can be displayed directly with a "Label" I think, what do you say?
Please see the updated example.
| ```json | ||
| { | ||
| "type": "bitfield", | ||
| "bytes": 20, |
There was a problem hiding this comment.
Better use something like raw bitwidth for easier indexing of the variables.
There was a problem hiding this comment.
I think it is common to have byte-based encodings but with bitwidth we could define a node that starts or ends mid-byte, for example 12 bits, then a uint of 8 bits, then 12 bits.
So I added bitwidth as an optional alternative to bytes. Hope that works.
There was a problem hiding this comment.
It might even allow for an enum type encoding for packed parameters. So you have these bytes representing an address, and these 2 bits, signalling some flags, etc. I think that would be helpful for Uniswap type descriptors. Will come back to it once I see how that has been encoded here.
…iptor - Object field entries may carry `offset`, a relative byte skip before decoding. - Wrap the `countFrom` snippet in a complete `completeTransfer` descriptor so the sibling relationship between `numSignatures` and `signatures` is visible. - Add `offset` to the JSON schema and use it in the Wormhole example. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ield Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Avoids clashing with ERC-7730's `fields`, whose items are identified by `path`. Updates spec, schema and examples. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…n bitranges - Add "Addressing entries" section: entry `name` is a path segment usable by ERC-7730 display fields, with rules for naming, switch, display and conflicts. - Allow `label`, `format`, `params`, `visible` on bitranges entries and constrain entry `name` to an identifier pattern in the schema. - Replace the tiny bitfield example with a full Uniswap v4 descriptor showing both inline and path-based display. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…` definition Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
…ges example - `bytes` nodes must set exactly one of `length`, `lengthFrom` or `toEnd`. - Add example-lifi-packed-bridges.json covering the cBridge, Hop and Across V4 Min/Packed functions, checked against the facet sources and the schema. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
I added an example file to elaborate the distinction. Thank you for the review, it was extremely helpful! Regarding the LiFi support, I will continue the investigation but seems like nothing should cause a major issue in these functions, but they did trigger a minor change in the ERC: |
…yte values (e.g. bytes32 labels)
- `string` (like `bytes`) must set exactly one of `length`, `lengthFrom`, `toEnd`. - Trailing zeros are stripped only for `length`; reject non-NFC text. - Move the banned-character list into a table; soften the uniqueness claim. - Mention `string` among entry value types; update the Zodiac example. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
`~.` names the enclosing `object` in a customEncoding tree, or the decoded payload of a `switch` case. It is optional but recommended, and replaces `.[]` with `~.[]` for nameless arrays. A string `operation.expression` is a path. Examples updated to match. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
| "label": "Execution", | ||
| "switch": { | ||
| "expression": { | ||
| "path": "mode.callType" |
There was a problem hiding this comment.
We need also an identifier here (could very well be ~) to denote that this is also a pre-decoded path variable.
Also, we may need to assert that a switch can be of certain types only.
…ike attributes customEncoding moves from a field key to `format: "customEncoding"` with the root node in `params`, so it looks like every other ERC-7730 format. Object entries are declared like fields (label, visible, format, params) and may omit `schema` when their `format` implies a layout. The decoded type must suit the format. `~.` paths may refer to any sibling entry. Add a `name` and `path` section explaining declaring vs looking up, with one example for each way of displaying an entry. Document the switch case-value form and that wallets MAY show a customEncoding field's label as a section header. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Make customEncoding a format; field-like object entries; explain name vs path
Remove the features that are deferred from the core profile and carry them in a separate PR instead. Specification text, JSON schema and examples are all affected. Features moved: - Inline `switch` node (a switch that reads its expression from the buffer at the cursor), including `payloadFrom` - Byte-aligned `bitfield` node and `bitranges` - ASCII/UTF-8 `string` node, including the NFC and bidi display rules - Literal `count` on `sequence` - `countFrom` on `sequence` - Packed Uniswap V3 `path` (the ERC had no text for it, so nothing to remove) Specification (ERCS/erc-0000.md): - Remove the `bitfield` and `string` sections, the inline `switch` section and the `count`/`countFrom` text. - Remove the Test Cases that depend on them: Uniswap v4 initialize, Zodiac Roles v2 and Wormhole Token Bridge. - Reword references that would otherwise dangle (node type list, `bitranges`, `lengthFrom`, `beforeSwap`, and the Balancer example link). Schema (erc7730-non-abi-dispatch.schema.json): - Remove the `string`, `bitfield` and `switchNode` definitions and the `count`/`countFrom` properties of `sequence`. Examples removed: - example-uniswap-v4-initialize.json (bitfield) - example-zodiac-roles.json (string) - example-wormhole-token-bridge.json (countFrom, inline switch) - example-balancer-relayer-library.json (inline switch) Co-Authored-By: Claude Sonnet 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01S9y93SSYgcjrrYsbZycSXr
|
The commit e5f8d3d (as a parent of ca42f1e) contains errors. |
When opening a pull request to submit a new EIP, please use the suggested template: https://github.com/ethereum/EIPs/blob/master/eip-template.md
We have a GitHub bot that automatically merges some PRs. It will merge yours immediately if certain criteria are met: