@@ -13,24 +13,28 @@ contract DiamondInspectFacet {
1313 bytes32 constant DIAMOND_STORAGE_POSITION = keccak256 ("erc8109.diamond " );
1414
1515 /**
16- * @notice Data stored for each function selector.
17- * @dev Facet address of function selector.
18- * Position of selector in the 'bytes4[] selectors' array.
16+ * @notice Data stored for each function selector
17+ * @dev Facet address of function selector
18+ * Position of selector in the 'bytes4[] selectors' array
1919 */
20- struct FacetAndPosition {
20+ struct FacetNode {
2121 address facet;
22- uint32 position;
22+ bytes4 prevFacetSelector;
23+ bytes4 nextFacetSelector;
24+ }
25+
26+ struct FacetList {
27+ uint32 facetCount;
28+ bytes4 firstFacetSelector;
29+ bytes4 lastFacetSelector;
2330 }
2431
2532 /**
2633 * @custom:storage-location erc8042:erc8109.diamond
2734 */
2835 struct DiamondStorage {
29- mapping (bytes4 functionSelector = > FacetAndPosition) facetAndPosition;
30- /**
31- * Array of all function selectors that can be called in the diamond.
32- */
33- bytes4 [] selectors;
36+ mapping (bytes4 functionSelector = > FacetNode) facetNodes;
37+ FacetList facetList;
3438 }
3539
3640 function getStorage () internal pure returns (DiamondStorage storage s ) {
@@ -48,7 +52,7 @@ contract DiamondInspectFacet {
4852 */
4953 function facetAddress (bytes4 _functionSelector ) external view returns (address facet ) {
5054 DiamondStorage storage s = getStorage ();
51- facet = s.facetAndPosition [_functionSelector].facet;
55+ facet = s.facetNodes [_functionSelector].facet;
5256 }
5357
5458 /**
@@ -60,7 +64,7 @@ contract DiamondInspectFacet {
6064 function facetFunctionSelectors (address _facet ) external view returns (bytes4 [] memory facetSelectors ) {
6165 DiamondStorage storage s = getStorage ();
6266 facetSelectors = IFacet (_facet).functionSelectors ();
63- if (facetSelectors.length == 0 || s.facetAndPosition [facetSelectors[0 ]].facet == address (0 )) {
67+ if (facetSelectors.length == 0 || s.facetNodes [facetSelectors[0 ]].facet == address (0 )) {
6468 facetSelectors = new bytes4 [](0 );
6569 }
6670 }
@@ -72,13 +76,14 @@ contract DiamondInspectFacet {
7276 */
7377 function facetAddresses () external view returns (address [] memory allFacets ) {
7478 DiamondStorage storage s = getStorage ();
75- bytes4 [] memory selectors = s.selectors ;
76- uint256 facetCount = selectors. length ;
79+ FacetList memory facetList = s.facetList ;
80+ uint256 facetCount = facetList.facetCount ;
7781 allFacets = new address [](facetCount);
78- for (uint256 selectorIndex; selectorIndex < facetCount; selectorIndex++ ) {
79- bytes4 selector = selectors[selectorIndex];
80- address facet = s.facetAndPosition[selector].facet;
81- allFacets[selectorIndex] = facet;
82+ bytes4 currentSelector = facetList.firstFacetSelector;
83+ for (uint256 i; i < facetCount; i++ ) {
84+ address facet = s.facetNodes[currentSelector].facet;
85+ allFacets[i] = facet;
86+ currentSelector = s.facetNodes[currentSelector].nextFacetSelector;
8287 }
8388 }
8489
@@ -95,15 +100,63 @@ contract DiamondInspectFacet {
95100 */
96101 function facets () external view returns (Facet[] memory facetsAndSelectors ) {
97102 DiamondStorage storage s = getStorage ();
98- bytes4 [] memory selectors = s.selectors;
99- uint256 facetCount = selectors.length ;
103+ FacetList memory facetList = s.facetList;
104+ uint256 facetCount = facetList.facetCount;
105+ bytes4 currentSelector = facetList.firstFacetSelector;
100106 facetsAndSelectors = new Facet [](facetCount);
101- for (uint256 selectorIndex; selectorIndex < facetCount; selectorIndex++ ) {
102- bytes4 selector = selectors[selectorIndex];
103- address facet = s.facetAndPosition[selector].facet;
107+ for (uint256 i; i < facetCount; i++ ) {
108+ address facet = s.facetNodes[currentSelector].facet;
104109 bytes4 [] memory facetSelectors = IFacet (facet).functionSelectors ();
105- facetsAndSelectors[selectorIndex].facet = facet;
106- facetsAndSelectors[selectorIndex].functionSelectors = facetSelectors;
110+ facetsAndSelectors[i].facet = facet;
111+ facetsAndSelectors[i].functionSelectors = facetSelectors;
112+ currentSelector = s.facetNodes[currentSelector].nextFacetSelector;
113+ }
114+ }
115+
116+ struct FunctionFacetPair {
117+ bytes4 selector;
118+ address facet;
119+ }
120+
121+ /**
122+ * @notice Returns an array of all function selectors and their
123+ * corresponding facet addresses.
124+ *
125+ * @dev Iterates through the diamond's stored selectors and pairs
126+ * each with its facet.
127+ * @return pairs An array of `FunctionFacetPair` structs, each containing
128+ * a selector and its facet address.
129+ */
130+ function functionFacetPairs () external view returns (FunctionFacetPair[] memory pairs ) {
131+ DiamondStorage storage s = getStorage ();
132+ FacetList memory facetList = s.facetList;
133+ uint256 facetCount = facetList.facetCount;
134+ bytes4 currentSelector = facetList.firstFacetSelector;
135+ uint256 selectorCount;
136+ Facet[] memory facetsAndSelectors = new Facet [](facetCount);
137+ for (uint256 i; i < facetCount; i++ ) {
138+ address facet = s.facetNodes[currentSelector].facet;
139+ bytes4 [] memory facetSelectors = IFacet (facet).functionSelectors ();
140+ unchecked {
141+ selectorCount += facetSelectors.length ;
142+ }
143+ facetsAndSelectors[i].facet = facet;
144+ facetsAndSelectors[i].functionSelectors = facetSelectors;
145+ currentSelector = s.facetNodes[currentSelector].nextFacetSelector;
146+ }
147+ pairs = new FunctionFacetPair [](selectorCount);
148+ selectorCount = 0 ;
149+ for (uint256 i; i < facetCount; i++ ) {
150+ Facet memory facetsAndSelector = facetsAndSelectors[i];
151+ address facet = facetsAndSelector.facet;
152+ uint256 selectorsLength = facetsAndSelector.functionSelectors.length ;
153+ for (uint256 selectorIndex; selectorIndex < selectorsLength; selectorIndex++ ) {
154+ bytes4 selector = facetsAndSelector.functionSelectors[selectorIndex];
155+ pairs[selectorCount] = FunctionFacetPair (selector, facet);
156+ unchecked {
157+ selectorCount++ ;
158+ }
159+ }
107160 }
108161 }
109162
0 commit comments