Foundation contest - kenta's results

Building the new creative economy

General Information

Platform: Code4rena

Start Date: 24/02/2022

Pot Size: $75,000 USDC

Total HM: 21

Participants: 28

Period: 7 days

Judge: alcueca

Total Solo HM: 15

Id: 94

League: ETH

Foundation

Findings Distribution

Researcher Performance

Rank: 21/28

Findings: 2

Award: $442.06

๐ŸŒŸ Selected for report: 0

๐Ÿš€ Solo Findings: 0

Findings Information

Awards

292.7988 USDC - $292.80

Labels

bug
QA (Quality Assurance)

External Links

2022-02-foundation

1 Use safeTransferFrom instead of transferFrom.

Openzeppelin says that Usage of this method is discouraged, use safeTransferFrom whenever possible. In these cases, you can use safeTransferFrom.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L264 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketPrivateSale.sol#L177 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketCore.sol#L86 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketCore.sol#L97 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketCore.sol#L105

2 wrong description? (I am not sure.) ERC20 funds?

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/CollateralManagement.sol#L25-L26

3 delete unnecessary code. I think the following code is not necessary, because this function is internal and called only by _buy. In _buy the related nftContractToTokenIdToBuyPrice will be deleted.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L282-L292

4 delete unused variable name for return value.

For example, the variable name market is not used, so you can delete it.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/FETH.sol#L693 delete market https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/FETH.sol#L661 delete amount

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketCore.sol#L112 delete fetchAddress

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L358 delete amount

5 missing inputs validation. Length of nftContracts and tokenIds must be same

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L150-L158

if (nftContracts.length != tokenIds.length) revert SomethingError();

6 address is not necessary.

Type of param nftContract is address, so you donโ€™t need to convert it with address().

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L253

7 emit msg.sender and msg.value if contract receives ether.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/CollateralManagement.sol#L21

For example, receive() external payable { emit EtherReceived(msg.sender, msg.value); }

#0 - HardlyDifficult

2022-03-09T11:07:16Z

  • safeTransferFrom: We have had a few suggestions on this. ATM we are going to continue with transferFrom because it lowers risk of reentrancy. But we may revisit this in the future.
  • Incorrect comment: Thanks for pointing this out, we have removed the old comment.
  • delete unnecessary code: This code is used - e.g. when canceling an auction.
  • delete unused variable name: We added return names to help with documentation, but then it creates an inconsistent style. So we have updated to use the named params instead of return.
  • missing inputs validation: There were also a couple other reports of this, we have added a check to asset the lengths match.
  • address is not necessary: Yes, we have removed the unnecessary cast. This helps with readability.
  • emit: Thanks for the suggestion, but this is for the Treasury contract so out of scope of this contest.

#1 - alcueca

2022-03-17T09:49:41Z

Unadjusted score: 35

Findings Information

๐ŸŒŸ Selected for report: Dravee

Also found by: 0x1f8b, CertoraInc, TerrierLover, csanuragjain, gzeon, iain, kenta, rfa, robee, thankthedark

Labels

bug
G (Gas Optimization)

Awards

149.2608 USDC - $149.26

External Links

2022-02-foundation gas optimization

1 replace storage with memory.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L126 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L313 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L359 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L388 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L108 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L126 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L205 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L282 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L317 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L338 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketReserveAuction.sol#L535 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/FETH.sol#L236

2 Using cache at the beginning of the function to save gas. (before if statement)

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L336-L348

function _invalidateOffer(address nftContract, uint256 tokenId) private { Offer memory offer = nftContractToIdToOffer[nftContract][nftContract]; if (offer.expiration >= block.timestamp) {} }

3 No need to use cache.

Cached variable is used only one time in these functions, so you donโ€™t need to use cache.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L296 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L327 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L190 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketBuyPrice.sol#L305 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/FETH.sol#L236 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/FETH.sol#L382 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/FETH.sol#L662

For example,

if (nftContractToIdToOffer[nftContract][tokenId].buyer == msg.sender){}

4 code duplication.

You need to change visibility of getReserveAuctionIdFor to public. However, you can save gas for deployment by using getReserveAuctionIdFor in the following functions.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketReserveAuction.sol#L667 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketReserveAuction.sol#L587 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketReserveAuction.sol#L533

And you can also think of the following cases.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketReserveAuction.sol#L576 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketReserveAuction.sol#L657

uint256 auctionId = getReserveAuctionIdFor(nftContract, tokenId);

5 use initial value for uint256.

https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketCreators.sol#L94 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketCreators.sol#L155 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketCreators.sol#L193 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketFees.sol#L85 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketFees.sol#L101 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketOffer.sol#L161 https://github.com/code-423n4/2022-02-foundation/blob/main/contracts/mixins/NFTMarketReserveAuction.sol#L274

for (uint256 i; i < nftContracts.length; ++i){}

#0 - HardlyDifficult

2022-03-09T19:06:46Z

  • Replace storage with memory: We did some testing of the gas impact and found that storage is most often less gas than memory. The key here seems to be which slots are accessed. When memory is used it makes a full copy, so all the data is read. However often in logic we are able to return after reading just one of the datapoints in the struct. By using storage we only read the data that's required. As a general best practice we have been using storage unless memory is required in order to access the original data (e.g. to emit after a delete).
  • Cache at the beginning: That suggestion does seem to improve readability, but we tested that change and it increases gas costs by ~2.3k gas in the happy case (where we return before the memory line).
  • No need to cache: Generally these lines were added to make the code easier to follow. We tested a couple of the suggestions and found <100 gas savings.
  • Code duplication: The examples provided are just reading from a map. I'm not sure using the getter helps with readability. Tested the change and it did not seem to impact gas or size, so this is just a style preference.
  • Initial value for uint256: We tested making this change and did not find a measurable impact on gas. We'll keep the default values, which are redundant, for improved readability.

#1 - alcueca

2022-03-17T16:02:17Z

Without testing the gas savings, it's unfortunately difficult for wardens to ensure that the gas savings are real. Food for thought.

Score: 100

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax ยฉ 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter