// SPDX-License-Identifier: LGPL-3.0-onlypragmasolidity ^0.8.22;import"./libraries/LibDiamond.sol";
import { IDiamondCut } from"./interfaces/IDiamondCut.sol";
/**
* @title DeBoxOSDiamond
* @notice DeBox Protocol Diamond contract, contains all the facets(diff modules) of the DeBox Protocol.
* @author https://debox.pro
*/contractDeBoxOSDiamond{
/**
* @notice Initialize the contract with the contract owner and the diamondCutFacet
* @param _contractOwner The owner of the contract: can execute diamondCut
* @param _diamondCutFacet The diamondCutFacet address: for adding, replacing, or removing functions
*/constructor(address _contractOwner, address _diamondCutFacet) payable{
LibDiamond.setContractOwner(_contractOwner);
// Add the diamondCut external function from the diamondCutFacet
IDiamondCut.FacetCut[] memory cut =new IDiamondCut.FacetCut[](1);
bytes4[] memory functionSelectors =newbytes4[](1);
functionSelectors[0] = IDiamondCut.diamondCut.selector;
cut[0] = IDiamondCut.FacetCut({ facetAddress: _diamondCutFacet, action: IDiamondCut.FacetCutAction.Add, functionSelectors: functionSelectors });
LibDiamond.diamondCut(cut, address(0), "");
}
// Find facet for function that is called and execute the// function if a facet is found and return any value.// solhint-disable-next-line no-complex-fallbackfallback() externalpayable{
LibDiamond.DiamondStorage storage ds;
bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION;
// get diamond storage// solhint-disable-next-line no-inline-assemblyassembly {
ds.slot:= position
}
// get facet from function selectoraddress facet = ds.selectorToFacetAndPosition[msg.sig].facetAddress;
if (facet ==address(0)) {
revert LibDiamond.FunctionDoesNotExist();
}
// Execute external function from facet using delegatecall and return any value.// solhint-disable-next-line no-inline-assemblyassembly {
// copy function selector and any argumentscalldatacopy(0, 0, calldatasize())
// execute function call using the facetlet result :=delegatecall(gas(), facet, 0, calldatasize(), 0, 0)
// get any return valuereturndatacopy(0, 0, returndatasize())
// return any return value or error back to the callerswitch result
case0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
// Able to receive ether// solhint-disable-next-line no-empty-blocksreceive() externalpayable{ }
}
Contract Source Code
File 2 of 3: IDiamondCut.sol
// SPDX-License-Identifier: GPL v3pragmasolidity ^0.8.22;interfaceIDiamondCut{
enumFacetCutAction {
Add, // 0
Replace, // 1
Remove // 2
}
structFacetCut {
address facetAddress;
FacetCutAction action;
bytes4[] functionSelectors;
}
/// @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 _initfunctiondiamondCut(FacetCut[] calldata _diamondCut, address _init, bytescalldata _calldata) external;
/**
* @notice Emitted when the diamond cut is executed
*/eventDiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata);
}
Contract Source Code
File 3 of 3: LibDiamond.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.22;import { IDiamondCut } from"../interfaces/IDiamondCut.sol";
/// Implementation of EIP-2535 Diamond Standard/// https://eips.ethereum.org/EIPS/eip-2535libraryLibDiamond{
// Diamond specific errorserrorIncorrectFacetCutAction();
errorNoSelectorsInFacet();
errorFunctionAlreadyExists();
errorFacetAddressIsZero();
errorFacetAddressIsNotZero();
errorFacetContainsNoCode();
errorFunctionDoesNotExist();
errorFunctionIsImmutable();
errorInitZeroButCalldataNotEmpty();
errorCalldataEmptyButInitNotZero();
errorInitReverted();
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
eventSupportedInterfacesChanged(bytes4 interfaceIds, bool supported);
/// @dev keccak256("diamond.standard.diamond.storage");bytes32internalconstant DIAMOND_STORAGE_POSITION =hex"c8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c131c";
structFacetAddressAndPosition {
address facetAddress;
uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array
}
structFacetFunctionSelectors {
bytes4[] functionSelectors;
uint256 facetAddressPosition; // position of facetAddress in facetAddresses array
}
structDiamondStorage {
// maps function selector to the facet address and// the position of the selector in the facetFunctionSelectors.selectors arraymapping(bytes4=> FacetAddressAndPosition) selectorToFacetAndPosition;
// maps facet addresses to function selectorsmapping(address=> FacetFunctionSelectors) facetFunctionSelectors;
// facet addressesaddress[] facetAddresses;
// Used to query if a contract implements an interface.// Used to implement ERC-165.mapping(bytes4=>bool) supportedInterfaces;
// owner of the contractaddress contractOwner;
}
functiondiamondStorage() internalpurereturns (DiamondStorage storage $) {
bytes32 position = DIAMOND_STORAGE_POSITION;
// solhint-disable-next-line no-inline-assemblyassembly {
$.slot:= position
}
}
functioncontractOwner() internalviewreturns (address) {
return diamondStorage().contractOwner;
}
functionenforceIsContractOwner() internalview{
require(msg.sender== diamondStorage().contractOwner, "LibDiamond: Must be contract owner");
}
functionsetContractOwner(address _newOwner) internal{
DiamondStorage storage ds = diamondStorage();
address previousOwner = ds.contractOwner;
ds.contractOwner = _newOwner;
emit OwnershipTransferred(previousOwner, _newOwner);
}
/**
* @notice edit the supported interfaces for the diamond
*/functionsetSupportsInterface(bytes4 _interfaceId, bool _supported) internal{
DiamondStorage storage ds = diamondStorage();
if (ds.supportedInterfaces[_interfaceId] == _supported) return;
ds.supportedInterfaces[_interfaceId] = _supported;
emit SupportedInterfacesChanged(_interfaceId, _supported);
}
// Internal function version of diamondCutfunctiondiamondCut(IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytesmemory _calldata) internal{
for (uint256 facetIndex; facetIndex < _diamondCut.length;) {
IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action;
if (action == IDiamondCut.FacetCutAction.Add) {
addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} elseif (action == IDiamondCut.FacetCutAction.Replace) {
replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} elseif (action == IDiamondCut.FacetCutAction.Remove) {
removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors);
} else {
revert IncorrectFacetCutAction();
}
unchecked {
++facetIndex;
}
}
emit IDiamondCut.DiamondCut(_diamondCut, _init, _calldata);
initializeDiamondCut(_init, _calldata);
}
functionaddFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal{
if (_facetAddress ==address(0)) {
revert FacetAddressIsZero();
}
if (_functionSelectors.length==0) {
revert NoSelectorsInFacet();
}
DiamondStorage storage ds = diamondStorage();
uint96 selectorPosition =uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
// add new facet address if it does not existif (selectorPosition ==0) {
addFacet(ds, _facetAddress);
}
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length;) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
if (oldFacetAddress !=address(0)) {
revert FunctionAlreadyExists();
}
addFunction(ds, selector, selectorPosition, _facetAddress);
unchecked {
++selectorPosition;
++selectorIndex;
}
}
}
functionreplaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal{
if (_functionSelectors.length==0) {
revert NoSelectorsInFacet();
}
if (_facetAddress ==address(0)) {
revert FacetAddressIsZero();
}
DiamondStorage storage ds = diamondStorage();
uint96 selectorPosition =uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length);
// add new facet address if it does not existif (selectorPosition ==0) {
addFacet(ds, _facetAddress);
}
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length;) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
if (oldFacetAddress == _facetAddress) {
revert FunctionAlreadyExists();
}
removeFunction(ds, oldFacetAddress, selector);
addFunction(ds, selector, selectorPosition, _facetAddress);
unchecked {
++selectorPosition;
++selectorIndex;
}
}
}
functionremoveFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal{
if (_functionSelectors.length==0) {
revert NoSelectorsInFacet();
}
DiamondStorage storage ds = diamondStorage();
// if function does not exist then do nothing and returnif (_facetAddress !=address(0)) {
revert FacetAddressIsNotZero();
}
for (uint256 selectorIndex; selectorIndex < _functionSelectors.length;) {
bytes4 selector = _functionSelectors[selectorIndex];
address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress;
removeFunction(ds, oldFacetAddress, selector);
unchecked {
++selectorIndex;
}
}
}
functionaddFacet(DiamondStorage storage ds, address _facetAddress) internal{
enforceHasContractCode(_facetAddress);
ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length;
ds.facetAddresses.push(_facetAddress);
}
functionaddFunction(DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress) internal{
ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition;
ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector);
ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress;
}
functionremoveFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal{
if (_facetAddress ==address(0)) {
revert FunctionDoesNotExist();
}
// an immutable function is a function defined directly in a diamondif (_facetAddress ==address(this)) {
revert FunctionIsImmutable();
}
// replace selector with last selector, then delete last selectoruint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition;
uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length-1;
// if not the same then replace _selector with lastSelectorif (selectorPosition != lastSelectorPosition) {
bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition];
ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector;
ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition =uint96(selectorPosition);
}
// delete the last selector
ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop();
delete ds.selectorToFacetAndPosition[_selector];
// if no more selectors for facet address then delete the facet addressif (lastSelectorPosition ==0) {
// replace facet address with last facet address and delete last facet addressuint256 lastFacetAddressPosition = ds.facetAddresses.length-1;
uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
if (facetAddressPosition != lastFacetAddressPosition) {
address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition];
ds.facetAddresses[facetAddressPosition] = lastFacetAddress;
ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition;
}
ds.facetAddresses.pop();
delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition;
}
}
functioninitializeDiamondCut(address _init, bytesmemory _calldata) internal{
if (_init ==address(0)) {
if (_calldata.length!=0) {
revert InitZeroButCalldataNotEmpty();
}
} else {
if (_calldata.length==0) {
revert CalldataEmptyButInitNotZero();
}
if (_init !=address(this)) {
enforceHasContractCode(_init);
}
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytesmemoryerror) = _init.delegatecall(_calldata);
if (!success) {
if (error.length>0) {
// bubble up the errorrevert(string(error));
} else {
revert InitReverted();
}
}
}
}
functionenforceHasContractCode(address _contract) internalview{
uint256 contractSize;
// solhint-disable-next-line no-inline-assemblyassembly {
contractSize :=extcodesize(_contract)
}
if (contractSize ==0) {
revert FacetContainsNoCode();
}
}
}