Omniscia Tangible Audit

MarketplaceV2 Code Style Findings

MarketplaceV2 Code Style Findings

MV2-01C: Inefficient Repetitive Invocations of Getter Function

Description:

The FactoryModifiers::factory function is repetitively invoked in the referenced statements within the same code block.

Example:

contracts/MarketplaceV2.sol
364function _payStorage(
365 ITangibleNFT nft,
366 IERC20Metadata paymentToken,
367 uint256 tokenId,
368 uint256 _years
369) internal {
370 require(nft.storageRequired(), "STNR");
371 require(_years > 0, "YZ");
372
373 uint256 amount = IFactory(factory()).adjustStorageAndGetAmount(
374 nft,
375 paymentToken,
376 tokenId,
377 _years
378 );
379 //we take in default USD token
380 IERC20(address(paymentToken)).safeTransferFrom(
381 msg.sender,
382 IFactory(factory()).categoryOwnerWallet(nft),
383 amount
384 );
385 emit StorageFeePaid(address(nft), tokenId, address(paymentToken), msg.sender, amount);
386}

Recommendation:

We advise the result of the FactoryModifiers::factory function call to be cached to a local variable and utilized in place of the ensuing invocations on each code block, optimizing the code's gas cost.

Alleviation (1f394a00cc2ed1dc2020a9c07f982cff9029077d):

The repetitive invocations of the FactoryModifiers::factory getter function have been properly replaced by a local variable which is assigned to the FactoryModifiers::factory result, optimizing each function's gas cost.

MV2-02C: Inefficient mapping Lookups

Description:

The linked statements perform key-based lookup operations on mapping declarations from storage multiple times for the same key redundantly.

Example:

contracts/MarketplaceV2.sol
302Lot memory _lot = marketplaceLot[address(nft)][tokenId];
303require(_lot.seller == seller, "NOS");
304
305emit StopSelling(seller, address(nft), tokenId);
306delete marketplaceLot[address(nft)][tokenId];

Recommendation:

As the lookups internally perform an expensive keccak256 operation, we advise the lookups to be cached wherever possible to a single local declaration that either holds the value of the mapping in case of primitive types or holds a storage pointer to the struct contained.

Alleviation (1f394a00cc2ed1dc2020a9c07f982cff9029077d):

All referenced inefficient mapping lookups have been optimized to the greatest extent possible, significantly reducing the gas cost of the functions the statements were located in.

MV2-03C: Redundant Parenthesis Statements

Description:

The referenced statements are redundantly wrapped in parenthesis' (()).

Example:

contracts/MarketplaceV2.sol
236if ((address(this) == ownerOfNft) && (msg.sender == lot.seller)) {

Recommendation:

We advise them to be safely omitted, increasing the legibility of the codebase.

Alleviation (1f394a00cc2ed1dc2020a9c07f982cff9029077d):

The redundant parenthesis in the referenced statements have been safely omitted.

MV2-04C: Suboptimal Struct Declaration Style

Description:

The linked declaration style of a struct is using index-based argument initialization.

Example:

contracts/MarketplaceV2.sol
611marketplaceLot[nft][tokenId] = Lot(
612 ITangibleNFT(nft),
613 defUSD,
614 tokenId,
615 seller,
616 price,
617 address(0)
618);

Recommendation:

We advise the key-value declaration format to be utilized instead, greatly increasing the legibility of the codebase.

Alleviation (2ad448279d9e8e4b6edd94bcd2eb22129b6f7357):

The key-value declaration style has been properly replaced the index-based declaration, increasing the code's legibility.