Skip to content

feat: resolve nested struct members in slither-read-storage - #3075

Open
subashmokshya wants to merge 1 commit into
crytic:masterfrom
subashmokshya:feat/read-storage-nested-structs
Open

feat: resolve nested struct members in slither-read-storage#3075
subashmokshya wants to merge 1 commit into
crytic:masterfrom
subashmokshya:feat/read-storage-nested-structs

Conversation

@subashmokshya

Copy link
Copy Markdown

Summary

slither-read-storage did not fully resolve structs nested inside other structs. A nested-struct member (e.g. outer.middle) received a SlotInfo for the nested struct's starting slot, but its own members (outer.middle.inner, outer.middle.inner.a, ...) were never resolved — their elems were left empty, so their slots, sizes, and packing offsets were unavailable.

This PR makes _all_struct_slots recurse into any member that is itself a struct, resolving that member's sub-members relative to the nested struct's base slot, per Solidity's storage-layout rules (a nested struct occupies consecutive slots starting at the parent member's slot). Recursion is depth-agnostic, so arbitrarily deep nesting works.

Root cause

_all_struct_slots iterated only the top-level struct's elems_ordered. When a member's type was itself a Structure, the code computed the member's start slot but never descended into it. The new _all_nested_struct_slots helper reuses the existing _find_struct_var_slot slot arithmetic to resolve each sub-member against the nested struct's base slot, then recurses on any sub-member that is also a struct.

Changes

  • slither/tools/read_storage/read_storage.py: recurse into nested struct members in _all_struct_slots; add _all_nested_struct_slots helper.
  • tests/unit/tools/read_storage/test_nested_struct.py: new test covering two-level nesting (OuterMiddleInner), asserting exact slots for every member, packing offsets for the doubly-nested elementary members, and fully-qualified dotted names.

Test evidence

$ pytest tests/unit/tools/read_storage/ -q
21 passed

The new test fails on master (nested elems empty) and passes with this change. ruff check and ruff format --check are clean on both files.

Fixes #2077

🤖 Generated with Claude Code

A struct member that is itself a struct only received a slot for the
nested struct's starting location; its own members were never resolved,
so their slots, sizes, and packing offsets were unavailable.

Recurse into nested struct members, computing each member's slot relative
to the nested struct's base slot per Solidity's storage layout rules.
This handles arbitrary nesting depth.

Fixes crytic#2077

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@subashmokshya
subashmokshya requested a review from smonicas as a code owner August 6, 2026 12:36
@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

slither-read-storage: add support for nested structs

2 participants