-
Notifications
You must be signed in to change notification settings - Fork 0
/
Diamond.sol
54 lines (49 loc) · 2.02 KB
/
Diamond.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
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {LibDiamond} from "./libraries/LibDiamond.sol";
import {iDiamondCut} from "./interfaces/iDiamondCut.sol";
/**
* @dev EIP-2535 Diamond
*/
contract Diamond {
constructor(address _Dev, address _diamondCutFacet) payable {
LibDiamond.setDev(_Dev);
// Add the diamondCut external function from the diamondCutFacet
iDiamondCut.FacetCut[] memory cut = new iDiamondCut.FacetCut[](1);
bytes4[] memory functionSelectors = new bytes4[](1);
functionSelectors[0] = iDiamondCut.diamondCut.selector;
cut[0] = iDiamondCut.FacetCut({facetAddress: _diamondCutFacet, action: iDiamondCut.FacetCutAction.Add, functionSelectors: functionSelectors});
LibDiamond.diamondCut(cut, address(0), "");
}
/// @dev : Find facet for function that is called and execute
/// the function if a facet is found and return any value.
fallback() external payable {
LibDiamond.DiamondStorage storage ds;
bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
// get diamond storage
assembly {
ds.slot := position
}
// get facet from function selector
address facet = address(bytes20(ds.facets[msg.sig]));
require(facet != address(0), "FUNCTION_NOT_FOUND");
// execute external function from facet using delegatecall and return any value.
assembly {
// copy function selector and any arguments
calldatacopy(0, 0, calldatasize())
// execute function call using the facet
let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
// get any return value
returndatacopy(0, 0, returndatasize())
// return any return value or error back to the caller
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
receive() external payable {}
}