Conversation
There was a problem hiding this comment.
🟢 Approval recommended
The implementations are internally consistent, bounded appropriately, documented, and covered by focused fuzz tests.
Pull request overview
Adds MIP-8 page arithmetic and typed storage access utilities, with tests, documentation, dependency locking, and upstream Foundry CI support.
Changes:
- Adds
Pages,PageIndex,PageHandle, andWords. - Adds fuzz tests for page arithmetic and storage pointers.
- Updates Foundry configuration, dependencies, CI, and documentation.
File summaries
| File | Description |
|---|---|
src/utils/storage/Pages.sol |
Implements MIP-8 page and slot arithmetic. |
src/utils/storage/Words.sol |
Adds typed arbitrary-slot storage access. |
test/Pages.t.sol |
Tests page derivation and arithmetic. |
test/Words.t.sol |
Tests exact-slot reads and writes. |
README.md |
Documents the new storage utilities. |
foundry.toml |
Enables Monad and CI fuzz configuration. |
foundry.lock |
Locks the forge-std dependency. |
.gitmodules |
Configures the forge-std submodule. |
.github/workflows/test.yml |
Uses upstream Foundry and checks out submodules. |
Review details
- Files reviewed: 9/10 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
MIP-8 groups storage into 4 KiB pages of 128 slots, so contracts that lay their storage out by page need page and slot arithmetic. Pages gives them the PageIndex type, the PageHandle type that derives a page from its own storage slot, checked slot arithmetic that reverts past the end of storage, and one custom error for an offset outside a page. A PageHandle is a one-slot struct declared where the structure that uses the page lives, as a state variable or inside a struct, array, or mapping. Its page contains keccak256(abi.encode(slot)), where a dynamic array declared in its place would start its data, so distinct declarations get distinct pages. The slot itself is never written. Pages hands out slot numbers, and reading or writing one takes the same three lines of assembly in every consumer. Words.ref turns a slot number into a Word storage pointer once, in the library, so storage laid out by slot is plain Solidity at the call site. It takes uint256 to match Pages and adds no runtime dependency. It is named ref because solc 0.8.36 warns that at will become a keyword. Tests use forge-std, added as a test-only submodule, and check reverts with vm.expectRevert through a harness contract. CI now installs upstream Foundry, which ships Monad support since v1.8.0, checks out submodules, and runs the fuzz tests at 10,000 runs through the ci profile the workflow already selected but that was never defined. foundry.toml selects the Monad network family for local runs too.
mmv08
force-pushed
the
pageref-contract
branch
from
September 7, 2026 10:38
cb9842b to
f669630
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR adds two small storage libraries for MIP-8 pages and changes CI to use the upstream Foundry with added monad support.
Contracts added:
Pagesimplements the page and slot arithmetic from MIP-8 together with aPageIndextype andPageHandlestruct to reserve a storage slot for deriving the page from that slot number.Wordsis a helper to read and write storage without assembly, same approach as OZ's StorageSlot libA basic usage sketch: