forked from mudgen/diamond-2
-
Notifications
You must be signed in to change notification settings - Fork 2
/
DiamondCutFacet.sol
55 lines (52 loc) · 2.35 KB
/
DiamondCutFacet.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// SPDX-License-Identifier: MIT
pragma solidity ^0.7.1;
pragma experimental ABIEncoderV2;
/******************************************************************************\
* Author: Nick Mudge <nick@perfectabstractions.com> (https://twitter.com/mudgen)
/******************************************************************************/
import "../interfaces/IDiamondCut.sol";
import "../libraries/LibDiamond.sol";
contract DiamondCutFacet is IDiamondCut {
// Standard diamondCut external function
/// @notice Add/replace/remove any number of functions and optionally execute
/// a function with delegatecall
/// @param _diamondCut Contains the facet addresses and function selectors
/// @param _init The address of the contract or facet to execute _calldata
/// @param _calldata A function call, including function selector and arguments
/// _calldata is executed with delegatecall on _init
function diamondCut(
FacetCut[] calldata _diamondCut,
address _init,
bytes calldata _calldata
) external override {
LibDiamond.enforceIsContractOwner();
LibDiamond.DiamondStorage storage ds = LibDiamond.diamondStorage();
uint256 originalSelectorCount = ds.selectorCount;
uint256 selectorCount = originalSelectorCount;
bytes32 selectorSlot;
// Check if last selector slot is not full
if (selectorCount % 8 > 0) {
// get last selectorSlot
selectorSlot = ds.selectorSlots[selectorCount / 8];
}
// loop through diamond cut
for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) {
(selectorCount, selectorSlot) = LibDiamond.addReplaceRemoveFacetSelectors(
selectorCount,
selectorSlot,
_diamondCut[facetIndex].facetAddress,
_diamondCut[facetIndex].action,
_diamondCut[facetIndex].functionSelectors
);
}
if (selectorCount != originalSelectorCount) {
ds.selectorCount = uint16(selectorCount);
}
// If last selector slot is not full
if (selectorCount % 8 > 0) {
ds.selectorSlots[selectorCount / 8] = selectorSlot;
}
emit DiamondCut(_diamondCut, _init, _calldata);
LibDiamond.initializeDiamondCut(_init, _calldata);
}
}