feat: ERC-7201 Storage Layout#15299
Conversation
Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: Claude:claude-sonnet-4-6
… array sizes Assisted-by: Claude:claude-sonnet-4-6
…d packing loop Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: Claude:claude-sonnet-4-6
…n types Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: Claude:claude-sonnet-4-6
…positive Assisted-by: Claude:claude-sonnet-4-6
… ERC-7201 slots Assisted-by: Claude:claude-sonnet-4-6
…ic array Assisted-by: Claude:claude-sonnet-4-6
| }; | ||
| (bytes, 0, "inplace") | ||
| } | ||
| TypeKind::Custom(_) | TypeKind::Err(_) => (32, 1, "inplace"), |
There was a problem hiding this comment.
[Blocker] Contract/interface-typed fields fall through to unknown, so they are treated as 32-byte slot-boundary values instead of 20-byte packable addresses. I reproduced this with IERC20 token; bool paused;: the normal solc layout packs paused at slot 0 offset 20, but the ERC-7201 synthetic layout emits token as unknown and moves paused to the next slot.
Consider handling ItemId::Contract(_) with a solc-compatible contract label and 20-byte inplace storage info.
| for struct_id in hir.strukt_ids() { | ||
| let strukt = hir.strukt(struct_id); | ||
|
|
||
| let Some(struct_contract_id) = strukt.contract else { continue }; |
There was a problem hiding this comment.
[Suggestion] This skips every @custom:storage-location erc7201:* struct declared at file scope, because strukt.contract is None. Solidity accepts NatSpec on file-level structs, and a library-style accessor using that struct currently compiles but forge inspect FileStorageLib storageLayout --json returns empty storage/types. Consider including file-level annotated structs that are referenced by the target/library path, or otherwise documenting/rejecting that pattern.
There was a problem hiding this comment.
I haven't ever used this annotation at file scope. Might be hard to identify consumers. I'll think about it.
This implements ERC-7201 for
forge inspect storageLayout.Motivation
I was implementing a library contract that would have delcared its storage using this annotation but the declared storage doesn't show up in the storage layout inspection.
We use this layout inspection to detect harmful regressions in the storage layout when maintaining a delegatecall proxy's implementation.
For library functionality such as the ERC-1967 upgrade location (not implemented here) and ERC-7201
custom-storage-location, we would like to be able to detect and include these slots in the layout description.Without this feature, we would have to detect all of these locations ad-hoc.
Changes
hir_type_storage_infoto expand entries for the storageLayout inspection output