Skip to content
Lattice

DiamondValidationLib

Git Source

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

NameTypeDescription
idstringThe ERC-7201 namespace (e.g. "lattice.storage.Governor").

Returns

NameTypeDescription
<none>bytes32The 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

NameTypeDescription
idsstring[]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

NameTypeDescription
deployedVersionuint64The Diamond's current initialized version.
cutInitVersionuint64The 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

NameTypeDescription
slotbytes32The colliding storage slot.
firststringThe first namespace that mapped to slot.
secondstringThe 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

NameTypeDescription
deployeduint64The Diamond's current getInitializedVersion().
attempteduint64The reinitializer version the pending cut's _init would use.