Skip to content

Commit 61cdb30

Browse files
committed
packedSelectors improvements
1 parent 0ba89cf commit 61cdb30

File tree

1 file changed

+40
-105
lines changed

1 file changed

+40
-105
lines changed

src/diamond/DiamondUpgradeFacet.sol

Lines changed: 40 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -229,8 +229,7 @@ contract DiamondUpgradeFacet {
229229
* 32 bytes offset + 32 bytes array length + 4 bytes (at least one selector).
230230
* If facet address has no bytecode then return size will be 0.
231231
*/
232-
let size := returndatasize()
233-
if lt(size, 68) {
232+
if lt(returndatasize(), 68) {
234233
/**
235234
* error NoSelectorsForFacet(address) selector: 0x9c23886b
236235
*/
@@ -247,8 +246,15 @@ contract DiamondUpgradeFacet {
247246
* We point 'selectors' to ptr + 0x20 to skip the offset and point
248247
* directly to the Length word, making it a valid Solidity bytes array.
249248
*/
250-
size := sub(size, 0x20) // Adjust size to account for the 32-byte offset word
249+
let size := sub(returndatasize(), 0x20) // Adjust size to account for the 32-byte offset word
251250
returndatacopy(ptr, 0x20, size)
251+
252+
/**
253+
* 6. Integrity check
254+
* @param selectors
255+
* @param index
256+
*/
257+
252258
selectors := ptr
253259
/**
254260
* 6. Update Free Memory Pointer
@@ -300,8 +306,12 @@ contract DiamondUpgradeFacet {
300306
bytes4 prevFacetNodeId = facetList.lastFacetNodeId;
301307
address facet = _facets[0];
302308
bytes memory selectors = packedSelectors(facet);
303-
uint256 selectorsLength = selectors.length / 4;
304-
facetList.selectorCount += uint32(selectorsLength);
309+
uint256 selectorsLength;
310+
unchecked {
311+
selectorsLength = selectors.length / 4;
312+
facetList.selectorCount += uint32(selectorsLength);
313+
}
314+
305315
bytes4 currentFacetNodeId = at(selectors, 0);
306316
if (facetList.facetCount == 0) {
307317
facetList.firstFacetNodeId = currentFacetNodeId;
@@ -329,8 +339,10 @@ contract DiamondUpgradeFacet {
329339
}
330340
address nextFacet = _facets[i];
331341
selectors = packedSelectors(nextFacet);
332-
selectorsLength = selectors.length / 4;
333-
facetList.selectorCount += uint32(selectorsLength);
342+
unchecked {
343+
selectorsLength = selectors.length / 4;
344+
facetList.selectorCount += uint32(selectorsLength);
345+
}
334346
bytes4 nextFacetNodeId = at(selectors, 0);
335347
s.facetNodes[currentFacetNodeId] = FacetNode(facet, prevFacetNodeId, nextFacetNodeId);
336348
facet = nextFacet;
@@ -363,77 +375,6 @@ contract DiamondUpgradeFacet {
363375
s.facetList = facetList;
364376
}
365377

366-
function addFacetsOld(address[] calldata _facets) internal {
367-
DiamondStorage storage s = getDiamondStorage();
368-
if (_facets.length == 0) {
369-
return;
370-
}
371-
FacetList memory facetList = s.facetList;
372-
/*
373-
* Store current Free Memory Pointer to restore later.
374-
* This is use to reuse memory in each loop iteration.
375-
*/
376-
uint256 freeMemPtr;
377-
assembly ("memory-safe") {
378-
freeMemPtr := mload(0x40)
379-
}
380-
bytes4 prevFacetNodeId = facetList.lastFacetNodeId;
381-
bytes memory selectors = packedSelectors(_facets[0]);
382-
bytes4 currentFacetNodeId = at(selectors, 0);
383-
if (facetList.facetCount == 0) {
384-
facetList.firstFacetNodeId = currentFacetNodeId;
385-
} else {
386-
s.facetNodes[prevFacetNodeId].nextFacetNodeId = currentFacetNodeId;
387-
}
388-
for (uint256 i; i < _facets.length; i++) {
389-
uint256 selectorsLength;
390-
uint256 nextI;
391-
unchecked {
392-
nextI = i + 1;
393-
selectorsLength = selectors.length / 4;
394-
facetList.selectorCount += uint32(selectorsLength);
395-
}
396-
bytes memory nextSelectors;
397-
bytes4 nextFacetNodeId;
398-
if (nextI < _facets.length) {
399-
nextSelectors = packedSelectors(_facets[nextI]);
400-
nextFacetNodeId = at(nextSelectors, 0);
401-
}
402-
/*
403-
* Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
404-
* // have to fix this.
405-
*/
406-
assembly ("memory-safe") {
407-
mstore(0x40, freeMemPtr)
408-
}
409-
address oldFacet = s.facetNodes[currentFacetNodeId].facet;
410-
if (oldFacet != address(0)) {
411-
revert CannotAddFunctionToDiamondThatAlreadyExists(currentFacetNodeId);
412-
}
413-
address facet = _facets[i];
414-
s.facetNodes[currentFacetNodeId] = FacetNode(facet, prevFacetNodeId, nextFacetNodeId);
415-
emit DiamondFunctionAdded(currentFacetNodeId, facet);
416-
417-
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
418-
bytes4 selector = at(selectors, selectorIndex);
419-
oldFacet = s.facetNodes[selector].facet;
420-
if (oldFacet != address(0)) {
421-
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
422-
}
423-
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
424-
emit DiamondFunctionAdded(selector, facet);
425-
}
426-
prevFacetNodeId = currentFacetNodeId;
427-
selectors = nextSelectors;
428-
currentFacetNodeId = nextFacetNodeId;
429-
}
430-
unchecked {
431-
facetList.facetCount += uint32(_facets.length);
432-
}
433-
facetList.lastFacetNodeId = prevFacetNodeId;
434-
s.facetList = facetList;
435-
}
436-
437378
/**
438379
* @notice This struct is used to replace old facets with new facets.
439380
*/
@@ -461,9 +402,13 @@ contract DiamondUpgradeFacet {
461402
}
462403
bytes memory oldSelectors = packedSelectors(oldFacet);
463404
bytes memory newSelectors = packedSelectors(newFacet);
405+
uint256 selectorsLength;
406+
unchecked {
407+
selectorsLength = newSelectors.length / 4;
408+
}
464409
bytes4 oldCurrentFacetNodeId = at(oldSelectors, 0);
465410
bytes4 newCurrentFacetNodeId = at(newSelectors, 0);
466-
uint256 selectorsLength;
411+
467412
/**
468413
* Validate old facet exists.
469414
*/
@@ -490,8 +435,10 @@ contract DiamondUpgradeFacet {
490435
} else if (facet == oldFacet) {
491436
emit DiamondFunctionReplaced(newCurrentFacetNodeId, oldFacet, newFacet);
492437
} else {
493-
revert CannotAddFunctionToDiamondThatAlreadyExists(newCurrentFacetNodeId);
438+
revert CannotReplaceFunctionFromNonReplacementFacet(newCurrentFacetNodeId);
494439
}
440+
s.facetNodes[newCurrentFacetNodeId] =
441+
FacetNode(newFacet, oldFacetNode.prevFacetNodeId, oldFacetNode.nextFacetNodeId);
495442
/**
496443
* Update linked list.
497444
*/
@@ -506,40 +453,28 @@ contract DiamondUpgradeFacet {
506453
s.facetNodes[oldFacetNode.nextFacetNodeId].prevFacetNodeId = newCurrentFacetNodeId;
507454
}
508455
} else {
456+
/**
457+
* Same first selector, just replace in place.
458+
*/
459+
s.facetNodes[newCurrentFacetNodeId] =
460+
FacetNode(newFacet, oldFacetNode.prevFacetNodeId, oldFacetNode.nextFacetNodeId);
461+
emit DiamondFunctionReplaced(newCurrentFacetNodeId, oldFacet, newFacet);
509462
if (keccak256(oldSelectors) == keccak256(newSelectors)) {
510-
/**
511-
* Same selectors, replace.
512-
*/
513-
emit DiamondFunctionReplaced(newCurrentFacetNodeId, oldFacet, newFacet);
514-
s.facetNodes[newCurrentFacetNodeId] =
515-
FacetNode(newFacet, oldFacetNode.prevFacetNodeId, oldFacetNode.nextFacetNodeId);
516463
/**
517464
* Replace remaining selectors.
518465
*/
519-
unchecked {
520-
selectorsLength = newSelectors.length / 4;
521-
}
522466
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
523467
bytes4 selector = at(newSelectors, selectorIndex);
524-
emit DiamondFunctionReplaced(selector, oldFacet, newFacet);
525468
s.facetNodes[selector] = FacetNode(newFacet, bytes4(0), bytes4(0));
469+
emit DiamondFunctionReplaced(selector, oldFacet, newFacet);
526470
}
527471
continue;
528472
}
529-
/**
530-
* Same first selector, just replace in place.
531-
*/
532-
emit DiamondFunctionReplaced(newCurrentFacetNodeId, oldFacet, newFacet);
533473
}
534-
s.facetNodes[newCurrentFacetNodeId] =
535-
FacetNode(newFacet, oldFacetNode.prevFacetNodeId, oldFacetNode.nextFacetNodeId);
536474

537475
/**
538476
* Add or replace new selectors.
539477
*/
540-
unchecked {
541-
selectorsLength = newSelectors.length / 4;
542-
}
543478
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
544479
bytes4 selector = at(newSelectors, selectorIndex);
545480
address facet = s.facetNodes[selector].facet;
@@ -600,12 +535,6 @@ contract DiamondUpgradeFacet {
600535
if (facetNode.facet != facet) {
601536
revert CannotRemoveFacetThatDoesNotExist(facet);
602537
}
603-
/*
604-
* Restore Free Memory Pointer to reuse memory.
605-
*/
606-
assembly ("memory-safe") {
607-
mstore(0x40, freeMemPtr)
608-
}
609538
/**
610539
* Remove the facet from the linked list.
611540
*/
@@ -627,6 +556,12 @@ contract DiamondUpgradeFacet {
627556
delete s.facetNodes[selector];
628557
emit DiamondFunctionRemoved(selector, facet);
629558
}
559+
/*
560+
* Restore Free Memory Pointer to reuse memory.
561+
*/
562+
assembly ("memory-safe") {
563+
mstore(0x40, freeMemPtr)
564+
}
630565
}
631566
unchecked {
632567
facetList.facetCount -= uint32(_facets.length);

0 commit comments

Comments
 (0)