This is the core dispatch path used by the diamond proxy pattern. The fallback function is used to route unmatched calls to the facet registered for the called selector (msg.sig) in diamond storage.
functiondiamondFallback();
Execution Flow:
Loads DiamondStorage and resolves the facet address for the called selector.
Reverts if no facet is registered for the selector (see FunctionNotFound error).
Copies calldata to memory (calldatacopy) and executes delegatecall on the resolved facet.
Copies returndata (returndatacopy) and bubbles the exact result back to the caller.
Execution Context
delegatecall executes facet code in the diamond's context.
State writes happen inside the diamond storage, and msg.sender/msg.value are preserved from the original external call.
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.
functionaddFacets(address[]memory _facets);
Parameters:
Property
Type
Description
_facets
address[]
The facet addresses to add. Each must implement IFacet and return selectors from exportSelectors().
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).
Contract address implementing exportSelectors() that returns ABI-encoded bytes of 4-byte function selectors.
Returns:
Property
Type
Description
selectors
bytes
Packed 4-byte function selectors (length is a multiple of 4). Same memory layout as returned by exportSelectors(); may point into the staticcall return buffer.
Thrown by importSelectors when the facet returns data that is not valid ABI-encoded bytes (e.g. wrong offset, length not a multiple of 4, or length exceeds payload).
Signature:
error IncorrectSelectorsEncoding(address _facet);
Thrown by importSelectors when the facet address has no code (e.g. EOA or uninitialized contract).
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 layout compatibility.
Handle custom errors such as CannotAddFunctionToDiamondThatAlreadyExists and NoSelectorsForFacet to ensure robust error management.
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.