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
Rank: 20/28
Findings: 1
Award: $454.89
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: leastwood
Also found by: 0x1f8b, 0xliumin, 0xwags, CertoraInc, Dravee, IllIllI, Ruhum, TerrierLover, WatchPug, cmichel, csanuragjain, defsec, gzeon, hubble, jayjonah8, kenta, kirk-baird, rfa, robee
454.886 USDC - $454.89
Issue#1 : makeOffer for non existent NFT id is allowed and amount is locked Issue#2 : Input check for array lengths missing in adminCancelOffers Issue#3 : Unused inheritance in NFTMarketFees contract Issue#4 : NFT Owner should not be allowed to makeOffer for its own NFT ids
Title : makeOffer for non existent NFT id is allowed and amount is locked
If makeOffer for a non existent NFT id is created, the foundation marketplace allows it and locks the user funds for 24 hours. Its expected that foundation marketplace should not accept such request for Offer for invalid NFT id's and reject transaction.
A brief test case is given below with a token id 99999 which is non existent, should fail. but its passing.
describe("`makeOffer` for a non-existing tokenId", () => { const tokenIdNonExisting = 99999; beforeEach(async () => { tx = await market.connect(collector).makeOffer(nft.address, tokenIdNonExisting, price, { value: price }); expiry = await getFethExpectedExpiration(tx); }); it("Emits OfferMade", async () => { await expect(tx).to.emit(market, "OfferMade").withArgs(nft.address, tokenIdNonExisting, collector.address, price, expiry); }); });
Check for valid NFT id , by checking if owner exists for an NFT id, and then process any request if valid. Sample test case which should pass after the code fix changes.
it("revert if Nonexisting NFT token ID", async() => { const tokenIdNonExisting = 99999; await expect(nft.ownerOf(tokenIdNonExisting)).to.be.revertedWith( "VM Exception while processing transaction: reverted with reason string 'ERC721: owner query for nonexistent token'", ); });
Title : Input check for array lengths missing in adminCancelOffers
There is no check for the array length of nftContracts and tokenIds in the function adminCancelOffers of NFTMarketOffer.sol due to which some of the tokenIDs may not get cancelled.
Contract : NFTMarketOffer.sol
function adminCancelOffers( address[] calldata nftContracts, uint256[] calldata tokenIds, string calldata reason ) external onlyFoundationAdmin nonReentrant { if (bytes(reason).length == 0) { revert NFTMarketOffer_Reason_Required(); }
Check and revert if nftContracts.length != tokenIds.length
Title : Unused inheritance in NFTMarketFees contract
There is unused inheritance in the NFTMarketFees abstract contract.
Contract : NFTMarketFees.sol line#18
abstract contract NFTMarketFees is Constants, Initializable, FoundationTreasuryNode, NFTMarketCore, NFTMarketCreators, SendValueWithFallbackWithdraw { ...
Delete the inheritance use of NFTMarketCore and NFTMarketCreators
Title : NFT Owner should not be allowed to makeOffer for its own NFT ids
The foundation contract allows for the NFT owner to makeOffer for its own NFT id, which may not be a valid business case. The owner can make a very high offer so as to invalidate other offer from an valid Address.
Check if the address requesting makeOffer for the NFT id is not also the NFT ID owner, and revert in that case.
#0 - HardlyDifficult
2022-03-07T12:56:34Z
Thanks for the feedback!
#1 - alcueca
2022-03-17T09:47:52Z
Unadjusted score: 40 (+20 formatting)
#2 - alcueca
2022-03-24T17:54:43Z
Extra 10 points from #50