Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/diamond/DiamondInspectFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ contract DiamondInspectFacet {
function facetFunctionSelectors(address _facet) external view returns (bytes4[] memory facetSelectors) {
DiamondStorage storage s = getStorage();
facetSelectors = unpackSelectors(IFacet(_facet).exportSelectors());
if (facetSelectors.length == 0 || s.facetNodes[facetSelectors[0]].facet == address(0)) {
if (facetSelectors.length == 0 || s.facetNodes[facetSelectors[0]].facet != _facet) {
facetSelectors = new bytes4[](0);
}
}
Expand Down
61 changes: 34 additions & 27 deletions src/diamond/DiamondMod.sol
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,33 @@ function at(bytes memory selectors, uint256 index) pure returns (bytes4 selector
}
}

/*
* Add all selectors of a facet to the diamond, except the first.
*
* The first selector (index 0) is the facet's linked-list node identifier.
* It carries prev/next pointers and must be stored by the caller after
* resolving the linked-list position. This function stores the remaining
* selectors as leaf nodes with zero prev/next links.
*
* Reverts if any selector already belongs to a different facet.
* Returns the number of selectors processed (excluding the first).
*/
function addFacetSelectors(address _facet, bytes memory _selectors) returns (uint256 selectorsLength) {
DiamondStorage storage s = getDiamondStorage();
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors.
*/
selectorsLength = _selectors.length >> 2;
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(_selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(_facet, bytes4(0), bytes4(0));
}
}

function addFacets(address[] memory _facets) {
DiamondStorage storage s = getDiamondStorage();
uint256 facetLength = _facets.length;
Expand Down Expand Up @@ -235,23 +262,13 @@ function addFacets(address[] memory _facets) {
*/
s.facetNodes[prevFacetNodeId].nextFacetNodeId = currentFacetNodeId;
}
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors
*/
uint256 selectorsLength = selectors.length >> 2;
unchecked {
facetList.selectorCount += uint32(selectorsLength);
}
/*
* Add all selectors, except the first, to the diamond.
* The first selector was already extracted as currentFacetNodeId above.
* The returned count is used to update selectorCount.
*/
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
unchecked {
facetList.selectorCount += uint32(addFacetSelectors(facet, selectors));
}
/*
* Reset memory for the main loop.
Expand Down Expand Up @@ -296,23 +313,13 @@ function addFacets(address[] memory _facets) {
facet = nextFacet;
prevFacetNodeId = currentFacetNodeId;
currentFacetNodeId = nextFacetNodeId;
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors.
*/
selectorsLength = selectors.length >> 2;
/*
* Add all the selectors of the facet to the diamond, except the first selector.
* The first selector (currentFacetNodeId) is the pending linked-list node
* that will be stored in the next iteration once nextFacetNodeId is known.
*/
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
}
unchecked {
facetList.selectorCount += uint32(selectorsLength);
facetList.selectorCount += uint32(addFacetSelectors(facet, selectors));
}
/*
* Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
Expand Down
61 changes: 34 additions & 27 deletions src/diamond/DiamondUpgradeFacet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,33 @@ contract DiamondUpgradeFacet {
}
}

/*
* Add all selectors of a facet to the diamond, except the first.
*
* The first selector (index 0) is the facet's linked-list node identifier.
* It carries prev/next pointers and must be stored by the caller after
* resolving the linked-list position. This function stores the remaining
* selectors as leaf nodes with zero prev/next links.
*
* Reverts if any selector already belongs to a different facet.
* Returns the number of selectors processed (excluding the first).
*/
function addFacetSelectors(address _facet, bytes memory _selectors) internal returns (uint256 selectorsLength) {
DiamondStorage storage s = getDiamondStorage();
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors.
*/
selectorsLength = _selectors.length >> 2;
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(_selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(_facet, bytes4(0), bytes4(0));
}
}

function addFacets(address[] calldata _facets) internal {
DiamondStorage storage s = getDiamondStorage();
uint256 facetLength = _facets.length;
Expand Down Expand Up @@ -335,23 +362,13 @@ contract DiamondUpgradeFacet {
*/
s.facetNodes[prevFacetNodeId].nextFacetNodeId = currentFacetNodeId;
}
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors
*/
uint256 selectorsLength = selectors.length >> 2;
unchecked {
facetList.selectorCount += uint32(selectorsLength);
}
/*
* Add all selectors, except the first, to the diamond.
* The first selector was already extracted as currentFacetNodeId above.
* The returned count is used to update selectorCount.
*/
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
unchecked {
facetList.selectorCount += uint32(addFacetSelectors(facet, selectors));
}
/*
* Reset memory for the main loop.
Expand Down Expand Up @@ -396,23 +413,13 @@ contract DiamondUpgradeFacet {
facet = nextFacet;
prevFacetNodeId = currentFacetNodeId;
currentFacetNodeId = nextFacetNodeId;
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors.
*/
selectorsLength = selectors.length >> 2;
/*
* Add all the selectors of the facet to the diamond, except the first selector.
* The first selector (currentFacetNodeId) is the pending linked-list node
* that will be stored in the next iteration once nextFacetNodeId is known.
*/
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
}
unchecked {
facetList.selectorCount += uint32(selectorsLength);
facetList.selectorCount += uint32(addFacetSelectors(facet, selectors));
}
/*
* Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
Expand Down
61 changes: 34 additions & 27 deletions src/diamond/DiamondUpgradeMod.sol
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,33 @@ function at(bytes memory selectors, uint256 index) pure returns (bytes4 selector
}
}

/*
* Add all selectors of a facet to the diamond, except the first.
*
* The first selector (index 0) is the facet's linked-list node identifier.
* It carries prev/next pointers and must be stored by the caller after
* resolving the linked-list position. This function stores the remaining
* selectors as leaf nodes with zero prev/next links.
*
* Reverts if any selector already belongs to a different facet.
* Returns the number of selectors processed (excluding the first).
*/
function addFacetSelectors(address _facet, bytes memory _selectors) returns (uint256 selectorsLength) {
DiamondStorage storage s = getDiamondStorage();
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors.
*/
selectorsLength = _selectors.length >> 2;
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(_selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(_facet, bytes4(0), bytes4(0));
}
}

function addFacets(address[] calldata _facets) {
DiamondStorage storage s = getDiamondStorage();
uint256 facetLength = _facets.length;
Expand Down Expand Up @@ -308,23 +335,13 @@ function addFacets(address[] calldata _facets) {
*/
s.facetNodes[prevFacetNodeId].nextFacetNodeId = currentFacetNodeId;
}
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors
*/
uint256 selectorsLength = selectors.length >> 2;
unchecked {
facetList.selectorCount += uint32(selectorsLength);
}
/*
* Add all selectors, except the first, to the diamond.
* The first selector was already extracted as currentFacetNodeId above.
* The returned count is used to update selectorCount.
*/
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
unchecked {
facetList.selectorCount += uint32(addFacetSelectors(facet, selectors));
}
/*
* Reset memory for the main loop.
Expand Down Expand Up @@ -369,23 +386,13 @@ function addFacets(address[] calldata _facets) {
facet = nextFacet;
prevFacetNodeId = currentFacetNodeId;
currentFacetNodeId = nextFacetNodeId;
/*
* Shift right by 2 is the same as dividing by 4, but cheaper.
* We do this to get the number of selectors.
*/
selectorsLength = selectors.length >> 2;
/*
* Add all the selectors of the facet to the diamond, except the first selector.
* The first selector (currentFacetNodeId) is the pending linked-list node
* that will be stored in the next iteration once nextFacetNodeId is known.
*/
for (uint256 selectorIndex = 1; selectorIndex < selectorsLength; selectorIndex++) {
bytes4 selector = at(selectors, selectorIndex);
if (s.facetNodes[selector].facet != address(0)) {
revert CannotAddFunctionToDiamondThatAlreadyExists(selector);
}
s.facetNodes[selector] = FacetNode(facet, bytes4(0), bytes4(0));
}
unchecked {
facetList.selectorCount += uint32(selectorsLength);
facetList.selectorCount += uint32(addFacetSelectors(facet, selectors));
}
/*
* Restore Free Memory Pointer to reuse memory from packedSelectors() calls.
Expand Down
Loading
Loading