Skip to content

Allow multiple storage_namespace blocks in one verity_contract #1838

@Th0rgal

Description

@Th0rgal

Summary

verity_contract accepts exactly one storage_namespace declaration (Verity/Macro/Syntax.lean:54-55 + the grammar's (verityNamespaceSpec)? line at 81). This works for contracts with a single ERC-7201 namespace, but rules out faithful translations of upstream Solidity contracts that compose multiple namespaced storage layouts in one address.

Concrete blocker

UnlinkPool.sol (unlink-xyz/monorepo@4bc46c1f) carries three logically distinct ERC-7201 namespaces:

  • unlink.storage.State (in State.sol)
  • unlink.storage.UnlinkPoolRelayers (in UnlinkPool.sol)
  • The implicit unlink.storage.LazyIMTData carried by InternalLazyIMT

In cases/unlink_xyz/pool (feat/unlink-pool-port-scratchpad-helpers), the case currently flattens all three into a single storage_namespace "unlink.storage.UnlinkPoolRelayers" block, which loses the per-namespace slot rebasing that Solidity uses.

Proposal

Either:

(a) Multiple storage_namespace blocksverityNamespaceSpec becomes * instead of ?. Subsequent storage blocks attach to the most recent namespace declaration. The macro would walk the namespace list and rebase each storage block onto its keccak-namespace key.

(b) storage_block "<namespace>" { ... } form — a single verity_contract hosts multiple keyword blocks, each carrying its own ERC-7201 layout. Existing storage_namespace "..." + storage ... form remains as the single-namespace shortcut.

Relation to #1730

#1730 (Axis 4 — automatic ERC-7201 namespaced storage) discusses making the namespace automatic per contract. That conversation is broader than this single-vs-multi-namespace gap. We're filing this as a self-contained ticket because:

  1. It unblocks faithful Unlink translation today, regardless of which way Axis 4: Storage safety — automatic EIP-7201 namespaced storage #1730 lands.
  2. It's a syntactic / translator change rather than a default-policy change.

Definition of done

  • verity_contract accepts ≥1 storage_namespace/storage block pairs.
  • Smoke contract under Contracts/Smoke.lean exercises two namespaces in one contract (with #check_contract verifying storage-slot derivation).
  • #guard_msgs test pinning the rejection diagnostic when the same namespace key appears twice.
  • verity-benchmark cases/unlink_xyz/pool re-translation lands separate State / RelayerStorage / PoolStorage namespaces.

Subsumes the "W7" workaround listed in the spec-review of verity-benchmark#42.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions