Skip to content
Lattice

SafeDiamondCutLib

Git Source

Title: SafeDiamondCut Library

Author: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80)

Library that gates EIP-2535 diamond cuts behind EmergencyStop + a pinned Gnosis Safe multisig, then delegates the actual cut to DiamondLib.diamondCut. Introduces no new cut logic. The instant (no-delay) Safe-gated analogue of GovernedDiamondCutLib.

Three-layer pattern: this library holds all logic and the namespaced storage. The stateless SafeDiamondCut facet delegates its external calls here. AUTHORITY MODEL: a Safe collects M-of-N owner signatures off-chain, verifies the threshold on-chain in execTransaction, then calls the diamond with operation = Call, so the diamond sees msg.sender == theSafe. This module therefore does NOT re-verify signatures — it only trusts msg.sender == $._safe. The Safe MUST call with operation = Call; a DelegateCall would execute this facet's code in the Safe's own context (wrong msg.sender, wrong storage) and is unsupported.

Functions

safeDiamondCutStorage

Returns a storage reference to the SafeDiamondCutStorage struct.

function safeDiamondCutStorage() internal pure returns (SafeDiamondCutStorage storage $);

Returns

NameTypeDescription
$SafeDiamondCutStorage

__SafeDiamondCut_init

Initializes the SafeDiamondCut module by pinning the Safe authority.

Validates _safe is non-zero and is a real, sensibly-configured Safe whose on-chain getThreshold() meets _minThreshold (which must itself be > 0). Reverts ISafeAuthority.SafeDiamondCutZeroSafe, ISafeAuthority.SafeDiamondCutZeroThreshold, or ISafeAuthority.SafeDiamondCutThresholdTooLow otherwise. Must be called inside the preInitializer/postInitializer window. Does NOT register an ERC-165 interface: the canonical cut selector 0x1f931c1c is already registered by DiamondLib.registerInterface() (see the ERC165_MAP_ICUT_SLOT note above).

function __SafeDiamondCut_init(address _safe, uint256 _minThreshold) internal;

Parameters

NameTypeDescription
_safeaddressThe Safe multisig to pin as the cut authority.
_minThresholduint256The minimum signature threshold the pinned Safe must enforce.

_checkSafe

Reverts ISafeAuthority.SafeDiamondCutUnauthorized unless the caller is the pinned Safe.

Library internal functions inline into the calling facet, so msg.sender here is the original caller of the Diamond — i.e. the Safe when it dispatches with operation = Call.

function _checkSafe(SafeDiamondCutStorage storage $) private view;

Parameters

NameTypeDescription
$SafeDiamondCutStorage

_validateSafe

Validates a candidate Safe authority: non-zero, real Safe, threshold >= minimum (> 0).

function _validateSafe(address _safe, uint256 _minThreshold) private view;

Parameters

NameTypeDescription
_safeaddress
_minThresholduint256

setSafe

Rotates the pinned Safe authority to _newSafe. Self-administered: callable ONLY by the current pinned Safe, so only the existing multisig can hand authority to its successor.

_newSafe is validated exactly like the init Safe, re-asserting getThreshold() >= 1 (the minimum-meaningful threshold). Emits ISafeAuthority.SafeRotated.

function setSafe(address _newSafe) internal;

Parameters

NameTypeDescription
_newSafeaddressThe new Safe to pin as the cut authority.

safe

Returns the currently pinned Safe authority.

function safe() internal view returns (address);

Returns

NameTypeDescription
<none>address

diamondCut

Guarded diamond cut: reverts if emergency-stopped, then requires the caller to be the pinned Safe, then delegates to DiamondLib.diamondCut. Introduces no new cut logic — all selector-collision, immutable-function, bytecode-existence, and init-delegatecall handling is diamond-lib's.

function diamondCut(FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata) internal;

Parameters

NameTypeDescription
_diamondCutFacetCut[]The facet addresses, cut actions, and function selectors.
_initaddressThe address delegatecalled after the cut (address(0) to skip).
_calldatabytesThe calldata passed to _init.

emergencyRemoveCut

Zero-delay, REMOVAL-ONLY escape hatch: lets a guardian instantly unbind a compromised or buggy facet's selectors WITHOUT going through the Safe — and, by design, even while the normal cut path is halted by EmergencyStop. Deliberately constrained so a rogue guardian can only AMPUTATE code (every entry must be Remove), never add or replace it (that still requires diamondCut under the Safe authority), can never remove diamondCut itself or a stop-recovery selector (emergencyResume, removeGuardian, revokeRole; even when unfrozen), and can never remove a frozen selector.

Guard ordering mirrors GovernedDiamondCutLib.emergencyRemoveCut: (1) guardian-only authority; (2) NO checkNotStopped() — this is the panic button and must work while stopped; (3) removal-only (any Add/Replace reverts IEmergencyCut.EmergencyCutMustBeRemoveOnly); (4) entrypoint protection (diamondCut and EmergencyStopLib.isRecoverySelector revert IEmergencyCut.EmergencyCutEntrypointProtected) and frozen protection; (5) NO init delegatecall. Recorded in the SAME append-only registry and additionally emits IEmergencyCut.EmergencyCutExecuted. Liveness: a guardian can still trip the stop, which blocks diamondCut. Since the recovery selectors cannot be removed, the DEFAULT_ADMIN_ROLE holder can always revoke a hostile guardian, resume, and let the Safe cut again to restore anything removed. This assumes a live admin; with the admin role renounced a stop is permanent.

function emergencyRemoveCut(FacetCut[] calldata _cuts) internal;

Parameters

NameTypeDescription
_cutsFacetCut[]The facet cuts to apply; every entry MUST be a Remove (facetAddress == address(0)).

freezeSelectors

Permanently freezes _selectors: each becomes ineligible to be the target of a Replace/Remove in any future cut. Gated to the pinned Safe — the same authority that gates diamondCut. Append-only: already-frozen selectors are idempotent no-ops, and there is no unfreeze.

function freezeSelectors(bytes4[] calldata _selectors) internal;

Parameters

NameTypeDescription
_selectorsbytes4[]The function selectors to freeze.

_enforceNotFrozen

Reverts IFrozenSelectors.FrozenSelectorProtected if any Replace/Remove action in _diamondCut targets a frozen selector. Add actions are never inspected.

function _enforceNotFrozen(SafeDiamondCutStorage storage $, FacetCut[] calldata _diamondCut) private view;

Parameters

NameTypeDescription
$SafeDiamondCutStorage
_diamondCutFacetCut[]

cutCount

Returns the number of cuts applied so far (also the latest registry version).

function cutCount() internal view returns (uint256);

Returns

NameTypeDescription
<none>uint256

getCutRecord

Returns the immutable audit record for a given registry version.

Versions are 1-indexed; an unwritten version (0, or any value > cutCount) returns a zero-valued IUpgradeRegistry.CutRecord.

function getCutRecord(uint256 _version) internal view returns (IUpgradeRegistry.CutRecord memory);

Parameters

NameTypeDescription
_versionuint256The registry version to look up.

Returns

NameTypeDescription
<none>IUpgradeRegistry.CutRecord

isSelectorFrozen

Returns whether _selector is in the frozen set (protected from Replace/Remove).

function isSelectorFrozen(bytes4 _selector) internal view returns (bool);

Parameters

NameTypeDescription
_selectorbytes4The function selector to query.

Returns

NameTypeDescription
<none>bool

frozenSelectors

Returns the full set of frozen selectors.

function frozenSelectors() internal view returns (bytes4[] memory);

Returns

NameTypeDescription
<none>bytes4[]

previewCut

Pre-flight simulation of the frozen-selector guard against the current set, with no state change. Only Replace/Remove actions are inspected; a pure read of the frozen set (does NOT re-implement diamond-lib's collision/immutable/bytecode checks).

function previewCut(FacetCut[] calldata _cuts) internal view returns (bool ok, bytes4 offendingSelector);

Parameters

NameTypeDescription
_cutsFacetCut[]The candidate facet cuts to simulate.

Returns

NameTypeDescription
okbooltrue if no Replace/Remove in _cuts targets a frozen selector.
offendingSelectorbytes4The first frozen selector a Replace/Remove would touch (zero if ok).

verifyInterfaceRegistered

Verifies whether _interfaceId is currently advertised in the diamond's ERC-165 map.

Thin wrapper over the shared ERC-165 support read. Equivalent to supportsInterface.

function verifyInterfaceRegistered(bytes4 _interfaceId) internal view returns (bool);

Parameters

NameTypeDescription
_interfaceIdbytes4The ERC-165 interface identifier to check.

Returns

NameTypeDescription
<none>bool