Skip to content

perf(utils): build Yul storage mapping pointer generator for nonces - #901

Merged
mijinummi merged 1 commit into
MDTechLabs:mainfrom
SharifIbrahimDev:yul-nonce-slot-calculator-issue-849
Aug 20, 2026
Merged

perf(utils): build Yul storage mapping pointer generator for nonces#901
mijinummi merged 1 commit into
MDTechLabs:mainfrom
SharifIbrahimDev:yul-nonce-slot-calculator-issue-849

Conversation

@SharifIbrahimDev

Copy link
Copy Markdown
Contributor

Summary

This PR implements a gas-optimized Yul storage mapping pointer generator for message nonces (mapping(uint256 chainId => mapping(uint256 nonce => bool))), resolving issue #849.

Closes #849

Changes

1. contracts/utils/NonceSlotCalculator.sol [NEW]

Implements a Solidity library NonceSlotCalculator with functions:

  • slotForNonce(uint256 chainId, uint256 nonce): calculates storage slot assuming default mapping slot 0.
  • slotForNonceAt(uint256 chainId, uint256 nonce, uint256 mappingSlot): calculates storage slot for any arbitrary mapping storage slot.

Key Optimizations & Characteristics:

  • Zero Memory Allocation: Uses EVM scratch space (0x000x3f) to stage keys and intermediate hashes.
  • In-place Hashing: Computes outerSlot = keccak256(chainId ‖ mappingSlot) at 0x000x40, and subsequently innerSlot = keccak256(nonce ‖ outerSlot) by reusing the same scratch space slots.
  • Preserves Free Memory Pointer: Does not touch or advance 0x40, eliminating memory expansion gas costs for mapping lookups.
  • Solidity Storage Layout Compliant: Conforms to standard EVM nested mapping storage slot derivations.

2. test/utils/NonceSlotCalculatorHarness.sol [NEW]

Test harness contract exposing NonceSlotCalculator functions and verifying calculated slots directly against on-chain storage via sload.

3. test/utils/NonceSlotCalculator.test.ts [NEW]

Comprehensive unit tests using Hardhat, Mocha, and Chai:

  • Validates calculated storage slot matches actual slot written by Solidity for nonces[chainId][nonce].
  • Checks boundary and edge cases: (0, 0), large uint128 values, and type(uint256).max.
  • Validates slot uniqueness across distinct key pairs.
  • Validates arbitrary mappingSlot offsets with slotForNonceAt.
  • Verifies function state mutability (pure) guaranteeing zero memory expansion.

Test Results

  NonceSlotCalculator
    ✔ computes the slot that Solidity actually writes to for nonces[1][100]
    ✔ matches the reference slot for chainId=0, nonce=0 (zero keys)
    ✔ matches the reference slot for large chainId and nonce values
    ✔ matches the reference slot for max uint256 keys
    ✔ produces unique slots for distinct (chainId, nonce) pairs
    ✔ slots differ when only chainId changes
    ✔ slots differ when only nonce changes
    ✔ slotForNonceAt matches slotForNonce when mappingSlot is 0
    ✔ slotForNonceAt produces different slots for different mappingSlot values
    ✔ slotForNonceAt matches off-chain reference for non-zero mappingSlot
    ✔ does not advance the free memory pointer (0x40) during slot computation

  11 passing (9s)

@mijinummi
mijinummi merged commit b140814 into MDTechLabs:main Aug 20, 2026
1 check passed
@mijinummi

Copy link
Copy Markdown
Collaborator

LGTM!

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.

[PERF] Build Yul Storage Mapping Pointer Generator for Nonces

2 participants