After a line by line manual analysis and automated review, Guardian Audits has concluded that:
- Published
- Language
- Solidity
- Chains
- Ethereum
- Sector
- NFTs
- 0 Critical
- 0 High
- 4 Medium
- 7 Low
- 0 Informational
Scope
Overview
After a line by line manual analysis and automated review, Guardian Audits has concluded that:
- NFTR’s smart contracts have a LOW RISK SEVERITY
- NFTR’s smart contracts have an ACTIVE OWNERSHIP
- Important owner privileges –
withdraw,withdrawRNM,curateCollection,updateNamingCreditsProtocolFeeRecipient,shutOffAssignments,assignNamingCredits,setSpecialNames,updateNamingPriceEther,updateNamingPriceRNM,updateProtocolFeeRecipient,updateRnmNamingStartBlock - NFTR’s smart contract owner has multiple “write” privileges. Centralization risk correlated to the active ownership is LOW
Findings 11
-
NFTR-1 Medium Centralization Risk Centralization / Privilege Partially resolved
Description
The
owneraddress has the ability to repeatedly changenamingPriceRNMby callingupdateNamingPriceRNM, but the function lacks any lower and upper bounds on the input. As a result, the owner can modify theRNMprice to be as large as possible and frontrun a buyer’s transaction. This would lead to the user experiencing a larger decrease of assets than intended.Additionally, the
owneraddress holds potentially exploitative abilities to:withdraw,withdrawRNM,curateCollection,updateNamingCreditsProtocolFeeRecipient,shutOffAssignments,assignNamingCredits,setSpecialNames,updateNamingPriceEther,updateProtocolFeeRecipient,updateRnmNamingStartBlock.Recommendation
Consider defining lower and upper bounds on
namingPriceRNM.Furthermore, consider making
ownera multi-sig, optionally with a timelock for improved community oversight.Resolution
NFTR Team: - Owner privileges are controlled by a multi-sig.
- RNM and WETH user risks have been mitigated as a new parameters have been introduced in the changeName function (currencyQuantity) that ensures that the contract can only pull what the user intended.
- withdraw: has been eliminated as it wasn’t needed — ETH doesn’t have a way to get stuck in the contract.
- withdrawRNM: Exists as a failsafe mechanism so RNM doesn’t get stuck in the contract if a user decides to send RNM to it.
- curateCollection: a max of 10 collections can be curated.
- updateNamingCreditsProtocolFeeRecipient: updates can now be shutoff if the DAO decides to make that immutable.
- shutOffAssignments: This is meant to be able to shut off naming credit assignments if it’s the will of the DAO.
- assignNamingCredits: has been set to a max of 1,000 assignments.
- setSpecialNames: These names are set right after deploy and functionality is that no more than 1,000 special names can be set, which is how the protocol was designed.
- updateNamingPriceEther: can now be shut off at the DAO’s will
- updateProtocolFeeRecipient: updates can now be shutoff if the DAO decides to make that immutable.
- updateRnmNamingStartBlock: This is meant so that the contract owner can activate tokenomics functionality once RNM goes live.
-
NFTR-2 Medium Hold Farming Naming Not Free Logical Error Resolved
Description
According to the docs, if an NFT is curated and is in the hold farming period, naming can be free. However, the
changeNamefunction still expects payment in the specified currency even if the NFT collection is curated and in the hold farming period.Recommendation
Implement logic such that a NFT in the holding period can be named for free.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NFTR-3 Low Simpler Code Best Practices Resolved
Description
Line 336: Because
checkOwnershipmust get the owner and compare it against themsg.sender, the function can simply utilizegetOwnerinstead of duplicating the logic for retrieving the NFT owner.Line 363:
isTokenStructEmptycan simply bereturn token_in.collectionAddress == address(0) &&token_in.tokenId == 0;The statement itself returns a boolean so an if-else is not needed.Recommendation
Implement the above simplifications.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NFTR-4 Low Transfer vs TransferFrom Best Practices Resolved
Description
transferFromis used to transferRNMfrom theNFTRegistrycontract to the owner, but atransfercould be used instead so approvals can be avoided.Recommendation
Consider using the
transferfunction if the RNM token allows it.Resolution
NFTR Team: - The suggested changes were implemented.
-
NFTR-5 Low Validation Upon Name Transfer Best Practices Acknowledged
Description
transferNamecan potentially lead to an NFT’s name being overwritten without permission from the holder. There must be proper validation done by the marketplace to make sure people can’t arbitrarily send names to another person’s NFT.Recommendation
Ensure the marketplace contract has the necessary validation checks in place to only transfer a name if the to address acknowledges the transaction whether it is through a name purchase or some other means.
Resolution
NFTR Team: - Acknowledged. The marketplace contract will take care of this.
-
NFTR-6 Low Zero Address Checks Best Practices Resolved
Description
The constructor can benefit from zero address checks to help prevent errors during deployment.
Recommendation
Focus on creating seamless deploy scripts and consider adding zero address checks
Resolution
NFTR Team: - The suggested changes were implemented.
-
NFTR-7 Low Unnecessary Boolean Checks Optimization Resolved
Description
The contract frequently performs
variable == trueorvariable == falsewhich is unnecessary and gas inefficient.Recommendation
Replace
require(variable == true)withrequire(variable).Replace
require(variable == false)withrequire(!variable).Resolution
NFTR Team: - The suggested changes were implemented.
-
NFTR-8 Low Unnecessary Casting Optimization Resolved
Description
There is no need to cast
holdFarmingAddressto theIHoldFarminginterface in functions such ascurateCollectionas it was already declared with theIHoldFarmingtype. The variable was not cast ininitiateRetroactiveHoldFarming. The same can be said for thenamingCreditsAddressvariable.Recommendation
Consider removing the explicit casts to save gas.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NFTR-9 Low Typo Typo Resolved
Description
“Naiming” is misspelled in the comment.
Recommendation
Correct the spelling for cleaner docs.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NFTR-10 Medium Potential DoS Denial-of-Service Resolved
Description
The
initiateRetroactiveHoldFarmingfunction calls theinitiateHoldFarmingForNFTfunction in the Hold Farming contract 10,000 times. This may exceed the block gas limit and prevent any collection from getting curated.Recommendation
Ensure that the block gas limit limit is not exceed or consider executing calls to
initiateHoldFarmingForNFTin batches.Resolution
NFTR Team: - This function has been eliminated.
- Retroactive hold farming might be taken care of in a different way, if at all.
-
NFTR-11 Medium Lost Names With Burnable NFT Logical Error Acknowledged
Description
Consider the scenario where a user registers a special name for their ERC721-compliant burnable NFT. They then proceed to burn their NFT, and ownership is relinquished. As a result, the name of the NFT cannot be changed nor transferred. The special name, a coveted asset to the NFTR protocol, is now lost.
Recommendation
Consider whether or not this is expected behavior. If unexpected, add a function so that if an owner does not exist for a particular NFT, then that NFT’s registered name can be dereserved.
Resolution
NFTR Team: - This is expected behavior.
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.
