Upgrade the diamond by adding, replacing, and/or removing facets.
Execution order:
1
Add Facets
Attach new facet contracts and register their function selectors.
2
Replace Facets
Swap existing selectors to point to updated facet implementations.
3
Remove Facets
Unregister selectors that are no longer needed in the diamond.
Then, if _delegate != address(0), the diamond performs a delegatecall with _delegateCalldata and emits DiamondDelegateCall.
functionupgradeDiamond(
address[]calldata _addFacets,
FacetReplacement[]calldata _replaceFacets,
address[]calldata _removeFacets,
address _delegate,
bytescalldata _delegateCalldata,
bytes32 _tag,
bytescalldata _metadata
)external;
Parameters:
Property
Type
Description
_addFacets
address[]
Facet addresses to add
_replaceFacets
FacetReplacement[]
(oldFacet, newFacet) pairs to replace
_removeFacets
address[]
Facet addresses to remove
_delegate
address
Optional contract to delegatecall (address(0) to skip)
_delegateCalldata
bytes
Optional calldata to execute on _delegate
_tag
bytes32
Optional arbitrary metadata, such as release version
_metadata
bytes
Optional arbitrary metadata
Facet Requirement
Facets must implement exportSelectors() in order to make their selectors discoverable by diamonds.
Only the exported selectors will be added to the diamond.
Thrown by importSelectors when the staticcall to _facet.exportSelectors() fails.
Signature:
error ExportSelectorsCallFailed(address _facet);
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 all diamond upgrade operations are performed by authorized wallet. This facet is configure to use the unique owner, use the Upgrade Module to wrap around your own access control logic.
Always verify facet logic contracts are immutable and trusted before using it inside a diamond.
Ensure each facet’s exportSelectors() returns a valid packed selector list in deterministic order.
Carefully audit any optional post-upgrade delegatecall (delegate contract + calldata).
The upgradeDiamond function is critical: this function mutates the diamond’s selector routing and facet list.
Although this facet protected by Owner checks, it can optionally execute an unrestricted delegatecall after facet updates. Allowing changes to the diamond storage.
That being said, make sure to provide verified and trusted contract addresses to avoid any unwanted changes or vulnerabilities