Diamond
Author: Matter Labs
The helper library for managing the EIP-2535 diamond proxy.
Note: security-contact: security@matterlabs.dev
State Variables
DIAMOND_INIT_SUCCESS_RETURN_VALUE
Magic value that should be returned by diamond cut initialize contracts.
Used to distinguish calls to contracts that were supposed to be used as diamond initializer from other contracts.
bytes32 internal constant DIAMOND_INIT_SUCCESS_RETURN_VALUE =
0x33774e659306e47509050e97cb651e731180a42d458212294d30751925c551a2;
DIAMOND_STORAGE_POSITION
Storage position of DiamondStorage
structure.
bytes32 private constant DIAMOND_STORAGE_POSITION =
0xc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131b;
Functions
getDiamondStorage
function getDiamondStorage()
internal
pure
returns (DiamondStorage storage diamondStorage);
Returns
Name | Type | Description |
---|---|---|
diamondStorage | DiamondStorage | The pointer to the storage where all specific diamond proxy parameters stored |
diamondCut
Add/replace/remove any number of selectors and optionally execute a function with delegatecall
function diamondCut(DiamondCutData memory _diamondCut) internal;
Parameters
Name | Type | Description |
---|---|---|
_diamondCut | DiamondCutData | Diamond's facet changes and the parameters to optional initialization delegatecall |
_addFunctions
Add new functions to the diamond proxy
NOTE: expect but NOT enforce that _selectors
is NON-EMPTY array
function _addFunctions(
address _facet,
bytes4[] memory _selectors,
bool _isFacetFreezable
) private;
_replaceFunctions
Change associated facets to already known function selectors
NOTE: expect but NOT enforce that _selectors
is NON-EMPTY array
function _replaceFunctions(
address _facet,
bytes4[] memory _selectors,
bool _isFacetFreezable
) private;
_removeFunctions
Remove association with function and facet
NOTE: expect but NOT enforce that _selectors
is NON-EMPTY array
function _removeFunctions(address _facet, bytes4[] memory _selectors) private;
_saveFacetIfNew
Add address to the list of known facets if it is not on the list yet NOTE: should be called ONLY before adding a new selector associated with the address
function _saveFacetIfNew(address _facet) private;
_addOneFunction
*Add one function to the already known facet NOTE: It is expected but NOT enforced that:
_facet
is NON-ZERO address_facet
is already stored address inDiamondStorage.facets
_selector
is NOT associated by another facet*
function _addOneFunction(
address _facet,
bytes4 _selector,
bool _isSelectorFreezable
) private;
_removeOneFunction
Remove one associated function with facet
NOTE: It is expected but NOT enforced that _facet
is NON-ZERO address
function _removeOneFunction(address _facet, bytes4 _selector) private;
_removeFacet
remove facet from the list of known facets
NOTE: It is expected but NOT enforced that there are no selectors associated with _facet
function _removeFacet(address _facet) private;
_initializeDiamondCut
Delegates call to the initialization address with provided calldata
Used as a final step of diamond cut to execute the logic of the initialization for changed facets
function _initializeDiamondCut(address _init, bytes memory _calldata) private;
Events
DiamondCut
event DiamondCut(FacetCut[] facetCuts, address initAddress, bytes initCalldata);
Structs
SelectorToFacet
Utility struct that contains associated facet & meta information of selector
struct SelectorToFacet {
address facetAddress;
uint16 selectorPosition;
bool isFreezable;
}
Properties
Name | Type | Description |
---|---|---|
facetAddress | address | address of the facet which is connected with selector |
selectorPosition | uint16 | index in FacetToSelectors.selectors array, where is selector stored |
isFreezable | bool | denotes whether the selector can be frozen. |
FacetToSelectors
Utility struct that contains associated selectors & meta information of facet
struct FacetToSelectors {
bytes4[] selectors;
uint16 facetPosition;
}
Properties
Name | Type | Description |
---|---|---|
selectors | bytes4[] | list of all selectors that belong to the facet |
facetPosition | uint16 | index in DiamondStorage.facets array, where is facet stored |
DiamondStorage
The structure that holds all diamond proxy associated parameters
According to the EIP-2535 should be stored on a special storage key - DIAMOND_STORAGE_POSITION
struct DiamondStorage {
mapping(bytes4 selector => SelectorToFacet selectorInfo) selectorToFacet;
mapping(address facetAddress => FacetToSelectors facetInfo) facetToSelectors;
address[] facets;
bool isFrozen;
}
Properties
Name | Type | Description |
---|---|---|
selectorToFacet | mapping(bytes4 selector => SelectorToFacet selectorInfo) | A mapping from the selector to the facet address and its meta information |
facetToSelectors | mapping(address facetAddress => FacetToSelectors facetInfo) | A mapping from facet address to its selectors with meta information |
facets | address[] | The array of all unique facet addresses that belong to the diamond proxy |
isFrozen | bool | Denotes whether the diamond proxy is frozen and all freezable facets are not accessible |
FacetCut
Parameters for diamond changes that touch one of the facets
struct FacetCut {
address facet;
Action action;
bool isFreezable;
bytes4[] selectors;
}
Properties
Name | Type | Description |
---|---|---|
facet | address | The address of facet that's affected by the cut |
action | Action | The action that is made on the facet |
isFreezable | bool | Denotes whether the facet & all their selectors can be frozen |
selectors | bytes4[] | An array of unique selectors that belongs to the facet address |
DiamondCutData
Structure of the diamond proxy changes
struct DiamondCutData {
FacetCut[] facetCuts;
address initAddress;
bytes initCalldata;
}
Properties
Name | Type | Description |
---|---|---|
facetCuts | FacetCut[] | The set of changes (adding/removing/replacement) of implementation contracts |
initAddress | address | The address that's delegate called after setting up new facet changes |
initCalldata | bytes | Calldata for the delegate call to initAddress |
Enums
Action
Type of change over diamond: add/replace/remove facets
enum Action {
Add,
Replace,
Remove
}