@@ -198,7 +198,6 @@ contract DiamondUpgradeFacet {
198198 * We store it at ptr to reuse that memory immediately.
199199 */
200200 mstore (ptr, 0x3e62267c00000000000000000000000000000000000000000000000000000000 )
201- mstore (add (ptr, 0x04 ), _facet)
202201 /**
203202 * 3. Perform the staticcall.
204203 * We pass 0 for out and outSize to keep the return data in the
@@ -209,7 +208,7 @@ contract DiamondUpgradeFacet {
209208 gas (), // pass all available gas
210209 _facet, // target address
211210 ptr, // pointer to start of input
212- 0x24 , // input length (4 bytes for selector and 32 bytes for address )
211+ 0x4 , // input length (4 bytes for selector)
213212 0 , // output pointer, not used
214213 0 // output length, not used
215214 )
@@ -250,15 +249,13 @@ contract DiamondUpgradeFacet {
250249 */
251250 size := sub (size, 0x20 ) // Adjust size to account for the 32-byte offset word
252251 returndatacopy (ptr, 0x20 , size)
253-
254252 selectors := ptr
255-
256253 /**
257254 * 6. Update Free Memory Pointer
258255 * New Free Memory Pointer is after the copied selectors.
259256 * Solidity requires the Free Memory Pointer to be aligned to 32 bytes.
260257 * 1. add(ptr, size) - end of copied selectors
261- * 2. add(..., 0x1f) - round up to next 32-byte boundary
258+ * 2. add(..., 0x1f) - round up to next 32-byte boundary (0x1f is 31)
262259 * 3. and(..., not(0x1f)) - clear lower 5 bits to align to 32 bytes
263260 */
264261 mstore (
@@ -286,6 +283,93 @@ contract DiamondUpgradeFacet {
286283 }
287284
288285 function addFacets (address [] calldata _facets ) internal {
286+ DiamondStorage storage s = getDiamondStorage ();
287+ uint256 facetLength = _facets.length ;
288+ if (facetLength == 0 ) {
289+ return ;
290+ }
291+ FacetList memory facetList = s.facetList;
292+ /*
293+ * Store current Free Memory Pointer to restore later.
294+ * This is use to reuse memory in each loop iteration.
295+ */
296+ uint256 freeMemPtr;
297+ assembly ("memory-safe" ) {
298+ freeMemPtr := mload (0x40 )
299+ }
300+ bytes4 prevFacetNodeId = facetList.lastFacetNodeId;
301+ address facet = _facets[0 ];
302+ bytes memory selectors = packedSelectors (facet);
303+ uint256 selectorsLength = selectors.length / 4 ;
304+ facetList.selectorCount += uint32 (selectorsLength);
305+ bytes4 currentFacetNodeId = at (selectors, 0 );
306+ if (facetList.facetCount == 0 ) {
307+ facetList.firstFacetNodeId = currentFacetNodeId;
308+ } else {
309+ s.facetNodes[prevFacetNodeId].nextFacetNodeId = currentFacetNodeId;
310+ }
311+ if (facetLength == 1 ) {
312+ if (s.facetNodes[currentFacetNodeId].facet != address (0 )) {
313+ revert CannotAddFunctionToDiamondThatAlreadyExists (currentFacetNodeId);
314+ }
315+ s.facetNodes[currentFacetNodeId] = FacetNode (facet, prevFacetNodeId, bytes4 (0 ));
316+ }
317+ emit DiamondFunctionAdded (currentFacetNodeId, facet);
318+ for (uint256 selectorIndex = 1 ; selectorIndex < selectorsLength; selectorIndex++ ) {
319+ bytes4 selector = at (selectors, selectorIndex);
320+ if (s.facetNodes[selector].facet != address (0 )) {
321+ revert CannotAddFunctionToDiamondThatAlreadyExists (selector);
322+ }
323+ s.facetNodes[selector] = FacetNode (facet, bytes4 (0 ), bytes4 (0 ));
324+ emit DiamondFunctionAdded (selector, facet);
325+ }
326+ /*
327+ * Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
328+ */
329+ assembly ("memory-safe" ) {
330+ mstore (0x40 , freeMemPtr)
331+ }
332+ for (uint256 i = 1 ; i < facetLength; i++ ) {
333+ if (s.facetNodes[currentFacetNodeId].facet != address (0 )) {
334+ revert CannotAddFunctionToDiamondThatAlreadyExists (currentFacetNodeId);
335+ }
336+ address nextFacet = _facets[i];
337+ selectors = packedSelectors (nextFacet);
338+ selectorsLength = selectors.length / 4 ;
339+ facetList.selectorCount += uint32 (selectorsLength);
340+ bytes4 nextFacetNodeId = at (selectors, 0 );
341+ s.facetNodes[currentFacetNodeId] = FacetNode (facet, prevFacetNodeId, nextFacetNodeId);
342+ facet = nextFacet;
343+ prevFacetNodeId = currentFacetNodeId;
344+ currentFacetNodeId = nextFacetNodeId;
345+ emit DiamondFunctionAdded (currentFacetNodeId, facet);
346+ for (uint256 selectorIndex = 1 ; selectorIndex < selectorsLength; selectorIndex++ ) {
347+ bytes4 selector = at (selectors, selectorIndex);
348+ if (s.facetNodes[selector].facet != address (0 )) {
349+ revert CannotAddFunctionToDiamondThatAlreadyExists (selector);
350+ }
351+ s.facetNodes[selector] = FacetNode (facet, bytes4 (0 ), bytes4 (0 ));
352+ emit DiamondFunctionAdded (selector, facet);
353+ }
354+ /*
355+ * Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
356+ */
357+ assembly ("memory-safe" ) {
358+ mstore (0x40 , freeMemPtr)
359+ }
360+ }
361+ if (s.facetNodes[currentFacetNodeId].facet != address (0 )) {
362+ revert CannotAddFunctionToDiamondThatAlreadyExists (currentFacetNodeId);
363+ }
364+ s.facetNodes[currentFacetNodeId] = FacetNode (facet, prevFacetNodeId, bytes4 (0 ));
365+ unchecked {
366+ facetList.facetCount += uint32 (facetLength);
367+ }
368+ facetList.lastFacetNodeId = currentFacetNodeId;
369+ s.facetList = facetList;
370+ }
371+
372+ function addFacetsOld (address [] calldata _facets ) internal {
289373 DiamondStorage storage s = getDiamondStorage ();
290374 if (_facets.length == 0 ) {
291375 return ;
@@ -295,9 +379,9 @@ contract DiamondUpgradeFacet {
295379 * Store current Free Memory Pointer to restore later.
296380 * This is use to reuse memory in each loop iteration.
297381 */
298- uint256 freeMemoryPointerLocation ;
382+ uint256 freeMemPtr ;
299383 assembly ("memory-safe" ) {
300- freeMemoryPointerLocation := mload (0x40 )
384+ freeMemPtr := mload (0x40 )
301385 }
302386 bytes4 prevFacetNodeId = facetList.lastFacetNodeId;
303387 bytes memory selectors = packedSelectors (_facets[0 ]);
@@ -323,9 +407,10 @@ contract DiamondUpgradeFacet {
323407 }
324408 /*
325409 * Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
410+ * // have to fix this.
326411 */
327412 assembly ("memory-safe" ) {
328- mstore (0x40 , freeMemoryPointerLocation )
413+ mstore (0x40 , freeMemPtr )
329414 }
330415 address oldFacet = s.facetNodes[currentFacetNodeId].facet;
331416 if (oldFacet != address (0 )) {
@@ -370,9 +455,9 @@ contract DiamondUpgradeFacet {
370455 * Store current Free Memory Pointer to restore later.
371456 * This is use to reuse memory in each loop iteration.
372457 */
373- uint256 freeMemoryPointerLocation ;
458+ uint256 freeMemPtr ;
374459 assembly ("memory-safe" ) {
375- freeMemoryPointerLocation := mload (0x40 )
460+ freeMemPtr := mload (0x40 )
376461 }
377462 for (uint256 i; i < _replaceFacets.length ; i++ ) {
378463 address oldFacet = _replaceFacets[i].oldFacet;
@@ -396,9 +481,8 @@ contract DiamondUpgradeFacet {
396481 * Restore Free Memory Pointer to reuse memory.
397482 */
398483 assembly ("memory-safe" ) {
399- mstore (0x40 , freeMemoryPointerLocation )
484+ mstore (0x40 , freeMemPtr )
400485 }
401-
402486 if (oldCurrentFacetNodeId != newCurrentFacetNodeId) {
403487 /**
404488 * Write first selector with linking info, then process remaining.
@@ -505,9 +589,9 @@ contract DiamondUpgradeFacet {
505589 * Store current Free Memory Pointer to restore later.
506590 * This is use to reuse memory in each loop iteration.
507591 */
508- uint256 freeMemoryPointerLocation ;
592+ uint256 freeMemPtr ;
509593 assembly ("memory-safe" ) {
510- freeMemoryPointerLocation := mload (0x40 )
594+ freeMemPtr := mload (0x40 )
511595 }
512596 for (uint256 i = 0 ; i < _facets.length ; i++ ) {
513597 address facet = _facets[i];
@@ -526,7 +610,7 @@ contract DiamondUpgradeFacet {
526610 * Restore Free Memory Pointer to reuse memory.
527611 */
528612 assembly ("memory-safe" ) {
529- mstore (0x40 , freeMemoryPointerLocation )
613+ mstore (0x40 , freeMemPtr )
530614 }
531615 /**
532616 * Remove the facet from the linked list.
0 commit comments