NFTR engaged Guardian to review the security of its NFT name marketplace. From the 1st of April to the 8th of April, a team of 2 auditors reviewed the source code in scope.
- Published
- Review window
- April 1 to 8, 2023
- Language
- Solidity
- Chains
- Ethereum
- Sector
- NFTs
- 2 Critical
- 2 High
- 4 Medium
- 4 Low
- 0 Informational
Scope
Overview
NFTR engaged Guardian to review the security of its NFT name marketplace. From the 1st of April to the 8th of April, a team of 2 auditors reviewed the source code in scope.
Findings 12
-
NFTR-1 Critical Two Names For One Token Logical Error Resolved
Description
Names could be transferred to an NFT with an existing name but the
tokenByNamemapping still contains the overwritten name pointing to the NFT. As a result, two different names may point to the same NFT.Consider the following scenario:
- Alice owns an NFT with name “Alice”
- Bob owns an NFT with name “Bob”
- Name “Alice” is transferred to Bob’s NFT
tokenByNameis updated to reflect that “Alice” points to Bob’s NFT.tokenByNamestill has an entry for name “Bob” also pointing to Bob’s NFT.- It now appears that Bob is now the owner of both names “Bob” and “Alice”.
- A user purchases name “Bob” but ends up receiving name “Alice” upon transfer.
Recommendation
If a name may be transferred to an NFT with an existing name, dereserve the old name using
releaseTokenByName. -
NMKT-1 Critical No Bids Can Be Entered Logical Error Resolved
Description
Initially, when no bids have been entered, the
existingbid will have default values –address(0)as the collection and 0 for thetokenId. The zero address does not have functionownerOf, so the call togetOwnerwill revert. As a result, no bids can be entered.Recommendation
Bypass the ownership check when there are no existing bids.
-
NMKT-2 High Overwriting Previous Name Unexpected Behavior Resolved
Description
When a bid is accepted through
acceptBidForNameor an offered name is purchased throughbuyName, there is no check that the NFT the name shall be transferred to is already named. As a result, a user may unexpectedly lose their old name upon transfer.Recommendation
Consider if owned names should be overwritten upon transfer. If necessary, clearly document such behavior.
-
NMKT-3 High Griefing Name Sellers Griefing Resolved
Description
It is simple for a malicious actor to grief a seller by placing a bid higher than the previous and then withdrawing the bid or transferring the
tokenToto another address. As a result, any bids made with true buying intention are lost and the seller is unable to sell his name.Recommendation
Consider allowing for a few blocks to pass before the bid can be overwritten so that a malicious actor risks losing the funds sent to make the ineffectual bid.
-
NMKT-4 Medium Inaccurate Event Data Events Resolved
Description
string memory name = toLower(nftr.tokenName(collectionFrom, tokenFrom))is performed after the transfer is already made. As a result, the event doesn’t emit the name that has been transferred but the empty string.
Recommendation
Grab the name from the
toTokenor cache the name prior to transfer. -
NMKT-5 Medium Inconsistent Encoded Names Logical Error Resolved
Description
There may be potential issues stemming from name parameters being lowered when getting the NFT with the provided name, but the
encodedNamebeing produced from a non-parsed input.Consider the following scenario:
- Bob owns an NFT with name “DIGITAL”
- Alice calls
enterBidForNameand passes “digital” for the name parameter. - Bob calls
acceptBidForNamewith name “DIGITAL”, but the encoded name does not match the encoded name generated by Alice’s “digital”. - Bob’s transaction reverts and is unable to accept Alice’s bid.
Recommendation
Lower the inputted name prior to encoding.
-
NMKT-6 Medium Reset Offers on Fee Change Logical Error Resolved
Description
If the owner changes the
feePerc, even if they lower it, all offers with a different fee will need to be reset due to a fee mismatch. A seller would prefer a lower fee so it is unexpected for their offer to be rendered invalid.Recommendation
Compare the offer’s fee percentage against an upper bound rather than an exact check.
.
-
NMKT-7 Medium Unable To Withdraw Bid Unexpected Behavior Resolved
Description
There is potential for a user to be unable to withdraw their bid.
Consider the following scenario:
- Bob bids for the name “Alice”.
- He then receives the NFT named “Alice” through secondary markets or a direct transfer.
- Bob is unable to withdraw his bid value because he now owns the NFT named “Alice”.
Recommendation
Consider whether it is necessary to check for ownership when withdrawing a bid for a name.
If necessary, properly document such behavior for users.
.
-
NMKT-8 Low Unnecessary Casting Best Practices Resolved
Description
_WETHis already an address so it is unnecessary to cast it to one.Recommendation
Remove
address(_WETH)cast. -
NMKT-9 Low Using delete Best Practices Resolved
Description
deleteon a mapping entry can be used to reset to defaults rather than setting a zeroed off Offer/Bid.Recommendation
Consider using
deleteif only default values are necessary. -
NMKT-10 Low Improper Visibility Best Practices Resolved
Description
toLowerhas visibility public but it under the internal functions section.Recommendation
Consider marking the function with visibility internal or move it to a different section.
-
NMKT-11 Low Loop Optimization Optimization Resolved
Description
The length of
bStrcan be cached. Furthermore, because a name’s length is restricted in NFTR, the index can be incremented in auncheckedblock.Recommendation
Consider the above gas optimizations.
No findings match.
More from NFTR
Put your code through the same review.
This review started with a conversation about scope. Tell us what you are building and we will plan yours with you.
