|
| 1 | +// SPDX-FileCopyrightText: 2025 IEXEC BLOCKCHAIN TECH <[email protected]> |
| 2 | +// SPDX-License-Identifier: Apache-2.0 |
| 3 | + |
| 4 | +pragma solidity ^0.8.0; |
| 5 | + |
| 6 | +//*************************************************************************************\ |
| 7 | +//* Adapted from Nick Mudge <[email protected]> (https://twitter.com/mudgen) |
| 8 | +//* EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 |
| 9 | +//* |
| 10 | +//* Implementation of a diamond. |
| 11 | +//*************************************************************************************/ |
| 12 | + |
| 13 | +// Diamond proxy implementation adapted from Mudgen's to redirect |
| 14 | +// `receive` and `fallback` calls to the implementations in facets. |
| 15 | +// See diff at: https://github.com/iExecBlockchainComputing/PoCo/pull/223/commits/0562f982 |
| 16 | + |
| 17 | +import {LibDiamond} from "@mudgen/diamond-1/contracts/libraries/LibDiamond.sol"; |
| 18 | +import {IDiamondCut} from "@mudgen/diamond-1/contracts/interfaces/IDiamondCut.sol"; |
| 19 | +import {IDiamondLoupe} from "@mudgen/diamond-1/contracts/interfaces/IDiamondLoupe.sol"; |
| 20 | +import {IERC173} from "@mudgen/diamond-1/contracts/interfaces/IERC173.sol"; |
| 21 | +import {IERC165} from "@mudgen/diamond-1/contracts/interfaces/IERC165.sol"; |
| 22 | + |
| 23 | +// When no function exists for function called |
| 24 | +error FunctionNotFound(bytes4 _functionSelector); |
| 25 | + |
| 26 | +// This is used in diamond constructor |
| 27 | +// more arguments are added to this struct |
| 28 | +// this avoids stack too deep errors |
| 29 | +struct DiamondArgs { |
| 30 | + address owner; |
| 31 | + address init; |
| 32 | + bytes initCalldata; |
| 33 | +} |
| 34 | + |
| 35 | +contract Diamond { |
| 36 | + constructor(IDiamondCut.FacetCut[] memory _diamondCut, DiamondArgs memory _args) payable { |
| 37 | + LibDiamond.setContractOwner(_args.owner); |
| 38 | + LibDiamond.diamondCut(_diamondCut, _args.init, _args.initCalldata); |
| 39 | + |
| 40 | + // Code can be added here to perform actions and set state variables. |
| 41 | + } |
| 42 | + |
| 43 | + /** |
| 44 | + * `fallback` function must be added to the diamond with selector `0xffffffff`. |
| 45 | + * The function is defined in IexecEscrow(Native/Token) facet. |
| 46 | + */ |
| 47 | + fallback() external payable { |
| 48 | + _fallback(); |
| 49 | + } |
| 50 | + |
| 51 | + /** |
| 52 | + * `receive` function must be added to the diamond with selector `0x00000000`. |
| 53 | + * The function is defined in IexecEscrow(Native/Token) facet. |
| 54 | + */ |
| 55 | + receive() external payable { |
| 56 | + _fallback(); |
| 57 | + } |
| 58 | + |
| 59 | + // Find facet for function that is called and execute the |
| 60 | + // function if a facet is found and return any value. |
| 61 | + function _fallback() internal { |
| 62 | + LibDiamond.DiamondStorage storage ds; |
| 63 | + bytes32 position = LibDiamond.DIAMOND_STORAGE_POSITION; |
| 64 | + // get diamond storage |
| 65 | + assembly { |
| 66 | + ds.slot := position |
| 67 | + } |
| 68 | + // get facet from function selector |
| 69 | + address facet = ds.facetAddressAndSelectorPosition[msg.sig].facetAddress; |
| 70 | + if (facet == address(0)) { |
| 71 | + facet = ds.facetAddressAndSelectorPosition[0xffffffff].facetAddress; |
| 72 | + } |
| 73 | + if (facet == address(0)) { |
| 74 | + revert FunctionNotFound(msg.sig); |
| 75 | + } |
| 76 | + // Execute external function from facet using delegatecall and return any value. |
| 77 | + assembly { |
| 78 | + // copy function selector and any arguments |
| 79 | + calldatacopy(0, 0, calldatasize()) |
| 80 | + // execute function call using the facet |
| 81 | + let result := delegatecall(gas(), facet, 0, calldatasize(), 0, 0) |
| 82 | + // get any return value |
| 83 | + returndatacopy(0, 0, returndatasize()) |
| 84 | + // return any return value or error back to the caller |
| 85 | + switch result |
| 86 | + case 0 { |
| 87 | + revert(0, returndatasize()) |
| 88 | + } |
| 89 | + default { |
| 90 | + return(0, returndatasize()) |
| 91 | + } |
| 92 | + } |
| 93 | + } |
| 94 | +} |
0 commit comments