// SPDX-License-Identifier: FSL-1.1-MIT pragma solidity ^0.8.24; //******************************************************************************\ //* Author: Nick Mudge (https://twitter.com/mudgen) //* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 //* //* Implementation of a diamond. //******************************************************************************/ import { LibDiamond } from "./libraries/LibDiamond.sol"; import { IDiamondCut } from "./interfaces/IDiamondCut.sol"; // When no function exists for function called error FunctionNotFound(bytes4 _functionSelector); // This is used in diamond constructor // more arguments are added to this struct // this avoids stack too deep errors struct DiamondArgs { address owner; address init; bytes initCalldata; } contract Diamond { constructor(IDiamondCut.FacetCut[] memory _diamondCut, DiamondArgs memory _args) payable { LibDiamond.setContractOwner(_args.owner); LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); // Code can be added here to perform actions and set state variables. } function diamondCut(IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata) external { LibDiamond.diamondCut(_diamondCut, _init, _calldata); } // 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 = ds.facetAddressAndSelectorPosition[msg.sig].facetAddress; if (facet == address(0)) { revert FunctionNotFound(msg.sig); } // 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 { } }