Assessment reports>Voyage>Medium findings>Functions cannot be removed during upgrades
Category: Business Logic

Functions cannot be removed during upgrades

Medium Severity
Medium Impact
Medium Likelihood

Description

In getUpgrade(...),

bytes4[] storage existingSelectors = LibAppStorage
    .ds()
    .upgradeParam
    .existingSelectors[msg.sender];

it is populated with null values.

Therefore, the following loop to set the remove functions will never initiate:

for (uint256 i = 0; i < existingSelectors.length; ) {
    if (!newSelectorSet[existingSelectors[i]]) {
        LibAppStorage.ds().upgradeParam.selectorsRemoved[i].push(
            existingSelectors[i]
        );
    }

And the final IDiamondCut.FacetCut[] returned will not contain any of the remove instructions.

Impact

It will not be possible to remove functions from Voyage's interface using the intended functionality. It would be possible, however, to replace them with functions that do not perform any operations. This approach will, however, result in a very cluttered and confusing interface and should be avoided.

Recommendations

Populate existingSelectors by populating adding existingSelectors.push(selector) to the following:

for (uint256 i = 0; i < currentFacets.length; ) {
    IDiamondLoupe.Facet memory facet = currentFacets[i];
    for (uint256 j = 0; j < facet.functionSelectors.length; ) {
        bytes4 selector = facet.functionSelectors[j];
        newSelectors.push(selector);
        existingSelectorFacetMap[selector] = facet.facetAddress;
        existingSelectors.push(selector);
        unchecked {
            ++j;
        }
    }
    unchecked {
        ++i;
    }
}

Remediation

The upgrade functionality has been dropped entirely from the project, the issue has therefore been remediated.

Zellic © 2024Back to top ↑