Skip to main content

Diamond Module

This module provides core internal functions and storage management for diamond proxies.

Key Features
  • Provides functions for diamond proxy operations.
  • Manages diamond storage using a dedicated storage slot ("erc8153.diamond").
  • Supports facet registration and retrieval through internal mechanisms.

Storage

State Variables

PropertyTypeDescription
DIAMOND_STORAGE_POSITIONbytes32Storage slot position for the diamond. Value: keccak256("erc8153.diamond")

Diamond Storage

Definition
/** storage-location: erc8042:erc8153.diamond */
struct DiamondStorage {
mapping(bytes4 functionSelector => FacetNode) facetNodes;
FacetList facetList;
}

struct FacetList {
bytes4 headFacetNodeId;
bytes4 tailFacetNodeId;
uint32 facetCount;
uint32 selectorCount;
}

struct FacetNode {
address facet;
bytes4 prevFacetNodeId;
bytes4 nextFacetNodeId;
}

Functions

getDiamondStorage

function getDiamondStorage() pure returns (DiamondStorage storage s);

Returns:

PropertyTypeDescription
sDiamondStorageThe DiamondStorage struct in storage.

addFacets

Registers one or more facets to a diamond. For each facet, selectors are discovered by calling exportSelectors(). Each selector is then mapped to the facet in diamond storage. Reverts if any selector is already registered on the diamond.

function addFacets(address[] memory _facets) ;

Parameters:

PropertyTypeDescription
_facetsaddress[]The facet addresses to add. Each must implement IFacet and return selectors from exportSelectors().

importSelectors

Retrieves the function selectors exposed by a facet by calling its exportSelectors(). Validates the returned ABI-encoded bytes (offset, length, and that the payload length is a multiple of 4) and returns the packed selectors without copying (zero-copy decode). Used internally by addFacets.

function importSelectors(address _facet) view returns (bytes memory selectors);

Parameters:

PropertyTypeDescription
_facetaddressContract address implementing exportSelectors() that returns ABI-encoded bytes of 4-byte function selectors.

Returns:

PropertyTypeDescription
selectorsbytesPacked 4-byte function selectors (length is a multiple of 4). Same memory layout as returned by exportSelectors(); may point into the staticcall return buffer.

at

Returns the 4-byte function selector at the given index in a packed bytes array of selectors (e.g. from importSelectors or other selector packing).

function at(bytes memory selectors, uint256 index) pure returns (bytes4 selector);

Parameters:

PropertyTypeDescription
selectorsbytesPacked array of 4-byte function selectors (length must be a multiple of 4).
indexuint256Zero-based index of the selector to read (0 = first selector, 1 = second, etc.).

Returns:

PropertyTypeDescription
selectorbytes4The function selector at the given index.

Events

Errors

Best Practices

  • Ensure that facet registration functions (like addFacets and importSelectors) are called only during diamond initialization or controlled upgrade processes.
  • Verify that the DiamondStorage struct is correctly defined and that any new fields are added at the end to maintain storage compatibility.
  • Handle custom errors such as CannotAddFunctionToDiamondThatAlreadyExists and NoSelectorsForFacet to ensure robust error management.

Integration Notes

This module interacts directly with the diamond's shared storage at the DIAMOND_STORAGE_POSITION, which is identified by keccak256("erc8153.diamond").

All functions within this module read from and write to this shared storage. Changes to the facetList or other storage elements are immediately visible to any facet that accesses the same storage slot.

Was this helpful?
Last updated:

Newsletter

Get notified about releases, feature announcements, and technical deep-dives on building smart contracts with Compose.

No spam. Unsubscribe anytime.