Diamond Upgrade Facet
Diamond upgrade and management facet
- Manages facet lifecycle (add, replace, remove) within a diamond.
- Supports optional
delegatecallfor post-upgrade operations. - Emits events for all facet changes and delegate calls.
- Provides selector discovery mechanism via
exportSelectors.
Overview
This facet provides core diamond upgrade functionality, enabling the addition, replacement, and removal of facets. It orchestrates these operations through the diamond proxy and can optionally perform delegate calls for initialization or state modification. The facet also supports exporting its selectors for discovery.
Storage
OwnerStorage
FacetNode
FacetList
DiamondStorage
FacetReplacement
State Variables
| Property | Type | Description |
|---|---|---|
OWNER_STORAGE_POSITION | bytes32 | Diamond storage slot position for this module (Value: keccak256("erc173.owner")) |
DIAMOND_STORAGE_POSITION | bytes32 | Diamond storage slot position for this module (Value: keccak256("erc8153.diamond")) |
Functions
upgradeDiamond
Upgrade the diamond by adding, replacing, or removing facets. Facets are added first, then replaced, then removed. These events are emitted to record changes to facets: - FacetAdded(address indexed _facet) - FacetReplaced(address indexed _oldFacet, address indexed _newFacet) - FacetRemoved(address indexed _facet) If _delegate is non-zero, the diamond performs a delegatecall to _delegate using _delegateCalldata. The DiamondDelegateCall event is emitted. The delegatecall is done to alter a diamond's state or to initialize, modify, or remove state after an upgrade. However, if _delegate is zero, no delegatecall is made and no DiamondDelegateCall event is emitted. If _tag is non-zero or if _metadata.length > 0 then the DiamondMetadata event is emitted.
Parameters:
| Property | Type | Description |
|---|---|---|
_addFacets | address[] | Facets to add. |
_replaceFacets | FacetReplacement[] | (oldFacet, newFacet) pairs, to replace old with new. |
_removeFacets | address[] | Facets to remove. |
_delegate | address | Optional contract to delegatecall (zero address to skip). |
_delegateCalldata | bytes | Optional calldata to execute on _delegate. |
_tag | bytes32 | Optional arbitrary metadata, such as release version. |
_metadata | bytes | Optional arbitrary data. |
exportSelectors
Exports the function selectors of the DiamondUpgradeFacet This function is use as a selector discovery mechanism for diamonds
Returns:
| Property | Type | Description |
|---|---|---|
- | bytes | selectors The exported function selectors of the DiamondUpgradeFacet |
Events
Errors
Best Practices
- Ensure all diamond upgrade operations are performed by authorized accounts.
- Verify facet logic contracts have correct bytecode before adding or replacing.
- Safely manage the
delegatecallfunctionality for initialization or state modification after an upgrade.
Security Considerations
The upgradeDiamond function is critical and must be protected by robust access control to prevent unauthorized modifications. The facet uses delegatecall, which requires careful validation of the _delegate address and _delegateCalldata to prevent reentrancy or unintended state changes. Input validation for facet addresses and selector data is crucial. Potential risks include OwnerUnauthorizedAccount, NoSelectorsForFacet, NoBytecodeAtAddress, and DelegateCallReverted errors if inputs are invalid or delegate calls fail.