DiamondValidationLib
Title: DiamondValidationLib
Author: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80)
Pure, Foundry-native pre-flight validation for composing ERC-7201 modules into one
EIP-2535 Diamond. Generalizes StorageSlotVerificationTest's uniqueness check into a
reusable assertion: given a list of ERC-7201 namespaces, reverts on the first pair that
derives the same storage slot (a guaranteed storage collision).
Utility-library pattern: no own storage, no facet, no ERC-165 registration; errors declared here. Intended for deploy scripts and off-chain/on-chain pre-flight, NOT a hot path.
Functions
erc7201Slot
Derives the ERC-7201 storage slot for a namespace string.
keccak256(abi.encode(uint256(keccak256(bytes(id))) - 1)) & ~bytes32(uint256(0xff)).
function erc7201Slot(string memory id) internal pure returns (bytes32);Parameters
| Name | Type | Description |
|---|---|---|
| id | string | The ERC-7201 namespace (e.g. "lattice.storage.Governor"). |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | bytes32 | The 32-byte storage slot. |
assertNamespacesDisjoint
Reverts unless every namespace in ids derives a distinct ERC-7201 storage slot.
O(n^2) pairwise comparison — fine for the small module counts used at composition time. An empty or single-element array trivially passes.
function assertNamespacesDisjoint(string[] memory ids) internal pure;Parameters
| Name | Type | Description |
|---|---|---|
| ids | string[] | The list of ERC-7201 namespaces to check for mutual disjointness. |
assertReinitializerMonotonic
Reverts unless a pending cut's _init reinitializer version strictly advances past
the Diamond's current initialized version.
Pre-flight guard an upgrade workflow runs before broadcasting a diamondCut that carries
an _init: the callback must use a reinitializer version strictly greater than the live
getInitializedVersion(), otherwise diamond-lib's InitializableLib would either reject
it on-chain (wasting a broadcast) or, if the same initializer() were re-runnable, reset
critical state. Mirrors the strictly-increasing rule enforced by preReinitializer.
Pure — reads no storage; the caller supplies deployedVersion from a prior
getInitializedVersion() read.
function assertReinitializerMonotonic(uint64 deployedVersion, uint64 cutInitVersion) internal pure;Parameters
| Name | Type | Description |
|---|---|---|
| deployedVersion | uint64 | The Diamond's current initialized version. |
| cutInitVersion | uint64 | The reinitializer version the pending cut's _init would use. |
Errors
NamespaceCollision
Thrown when two namespaces derive the same ERC-7201 storage slot.
error NamespaceCollision(bytes32 slot, string first, string second);Parameters
| Name | Type | Description |
|---|---|---|
| slot | bytes32 | The colliding storage slot. |
| first | string | The first namespace that mapped to slot. |
| second | string | The second namespace that mapped to slot. |
InitializerWouldReRun
Thrown when a cut's _init reinitializer version would not advance past the Diamond's
current initialized version, so running it would re-execute an already-applied
initializer (e.g. replaying a v1 initialize after the Diamond is live).
error InitializerWouldReRun(uint64 deployed, uint64 attempted);Parameters
| Name | Type | Description |
|---|---|---|
| deployed | uint64 | The Diamond's current getInitializedVersion(). |
| attempted | uint64 | The reinitializer version the pending cut's _init would use. |