Omniscia Evergon Labs Audit

CreateFractionsSkeletonNID Manual Review Findings

CreateFractionsSkeletonNID Manual Review Findings

CFN-01M: Inexistent Forwarding of Native Funds

Description:

The CreateFractionsSkeletonNID::createFractions function fails to forward the native funds supplied to its call to the Erc1155FractionFacet::handleFractionPhase implementation resulting in a deployment failure and thus a failure in the creation of fractions.

Impact:

The CreateFractionsSkeletonNID::createFractions will fail to properly advance from the fraction creation phase as it does not supply sufficient funds for the cross-chain calls.

Example:

packages/contracts/contracts/skeletonFacets/NID/CreateFractionsSkeletonNID.sol
50function createFractions(
51 bytes calldata preFractionData,
52 bytes calldata fractionData,
53 bytes calldata postFractionData,
54 bool isMinting
55) external payable onlyExternalDelegateCall requireTxDataAuth {
56 address account = ERC2771RecipientStorage.layout()._msgSender();
57
58 uint256 nftId = IPreFractionFacet(address(this)).handlePreFractionPhase(preFractionData, account);
59 uint256 fractionsCreated = IFractionFacet(address(this)).handleFractionPhase(fractionData, nftId, account);

Recommendation:

We advise the code to properly forward native funds ensuring that the CreateFractionsSkeletonNID::createFractions will properly deploy a fractionalized NFT.

Alleviation (71cda4ccfdcfa25fb96a4565f1f8143b350dd246):

The referenced IFractionFacet::handleFractionPhase interaction will properly forward native funds in the updated code, alleviating this exhibit.

CFN-02M: Inexistent Storage of Data Point

Description:

The isMinting data point is not stored by the CreateFractionsSkeletonNID::createFractions function which will result in the PurcahseSkeletonNID::purchase function misbehaving as it will not properly detect that the fractions created are meant to be minted on purchase.

Impact:

Any fraction instance configured to be minted on purchase will fail to do so causing it to not be purchase-able.

Example:

packages/contracts/contracts/skeletonFacets/NID/CreateFractionsSkeletonNID.sol
50function createFractions(
51 bytes calldata preFractionData,
52 bytes calldata fractionData,
53 bytes calldata postFractionData,
54 bool isMinting
55) external payable onlyExternalDelegateCall requireTxDataAuth {
56 address account = ERC2771RecipientStorage.layout()._msgSender();
57
58 uint256 nftId = IPreFractionFacet(address(this)).handlePreFractionPhase(preFractionData, account);
59 uint256 fractionsCreated = IFractionFacet(address(this)).handleFractionPhase(fractionData, nftId, account);
60
61 if (isMinting && fractionsCreated != 0) revert NonZeroFractionsOnCreation();
62 GeneralStorage.Layout storage generalStorage = GeneralStorage.layout();
63
64 // Always store what generalStorage needs.
65 uint256 campaignId = generalStorage.currentId;
66
67 generalStorage.infoForId[campaignId].creator = account;
68 generalStorage.infoForId[campaignId].fractionsCreated = fractionsCreated;
69 generalStorage.infoForId[campaignId].nftId = nftId;
70
71 IPostFractionFacet(address(this)).handlePostFractionPhase(postFractionData);
72
73 emit FractionsCreated(nftId, campaignId, account, fractionsCreated);
74}

Recommendation:

We advise the relevant data point to be properly stored, ensuring that the CreateFractionsSkeletonNID::createFractions behaves as expected.

Alleviation (71cda4ccfdcfa25fb96a4565f1f8143b350dd246):

The isMinting data entry is properly stored to the relevant GeneralStorage.IdInfo data entry, alleviating this exhibit in full.