Skip to content
$1,000,000 in security audit grants are live now, Apply here →

Security review · July 2022

Protocol Review

for NFTR

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

8 resolved · 1 partially resolved · 2 acknowledged

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

  1. NFTR-1 Medium Centralization Risk Centralization / Privilege Partially resolved
    Location
    NFTRegistry.sol

    Description

    The owner address has the ability to repeatedly change namingPriceRNM by calling updateNamingPriceRNM, but the function lacks any lower and upper bounds on the input. As a result, the owner can modify the RNM price 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 owner address 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 owner a 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.
  2. NFTR-2 Medium Hold Farming Naming Not Free Logical Error Resolved
    Location
    NFTRegistry.sol

    Description

    According to the docs, if an NFT is curated and is in the hold farming period, naming can be free. However, the changeName function 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.

  3. NFTR-3 Low Simpler Code Best Practices Resolved
    Location
    NFTRegistry.sol: 336, 363

    Description

    Line 336: Because checkOwnership must get the owner and compare it against the msg.sender, the function can simply utilize getOwner instead of duplicating the logic for retrieving the NFT owner.

    Line 363: isTokenStructEmpty can simply be return 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.

  4. NFTR-4 Low Transfer vs TransferFrom Best Practices Resolved
    Location
    NFTRegistry.sol: 507

    Description

    transferFrom is used to transfer RNM from the NFTRegistry contract to the owner, but a transfer could be used instead so approvals can be avoided.

    Recommendation

    Consider using the transfer function if the RNM token allows it.

    Resolution

    NFTR Team: - The suggested changes were implemented.

  5. NFTR-5 Low Validation Upon Name Transfer Best Practices Acknowledged
    Location
    NFTRegistry.sol: 172

    Description

    transferName can 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.

  6. NFTR-6 Low Zero Address Checks Best Practices Resolved
    Location
    NFTRegistry.sol: 93

    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.

  7. NFTR-7 Low Unnecessary Boolean Checks Optimization Resolved
    Location
    NFTRegistry.sol

    Description

    The contract frequently performs variable == true or variable == false which is unnecessary and gas inefficient.

    Recommendation

    Replace require(variable == true) with require(variable).

    Replace require(variable == false) with require(!variable).

    Resolution

    NFTR Team: - The suggested changes were implemented.

  8. NFTR-8 Low Unnecessary Casting Optimization Resolved
    Location
    NFTRegistry.sol

    Description

    There is no need to cast holdFarmingAddress to the IHoldFarming interface in functions such as curateCollection as it was already declared with the IHoldFarming type. The variable was not cast in initiateRetroactiveHoldFarming. The same can be said for the namingCreditsAddress variable.

    Recommendation

    Consider removing the explicit casts to save gas.

    Resolution

    NFTR Team: - The suggested changes were implemented.

  9. NFTR-9 Low Typo Typo Resolved
    Location
    NFTRegistry.sol: 44

    Description

    “Naiming” is misspelled in the comment.

    Recommendation

    Correct the spelling for cleaner docs.

    Resolution

    NFTR Team: - The suggested changes were implemented.

  10. NFTR-10 Medium Potential DoS Denial-of-Service Resolved
    Location
    NFTRegistry.sol: 486

    Description

    The initiateRetroactiveHoldFarming function calls the initiateHoldFarmingForNFT function 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 initiateHoldFarmingForNFT in batches.

    Resolution

    NFTR Team: - This function has been eliminated.

    • Retroactive hold farming might be taken care of in a different way, if at all.
  11. NFTR-11 Medium Lost Names With Burnable NFT Logical Error Acknowledged
    Location
    NFTRegistry.sol

    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.

More from NFTR

  1. Marketplace

    12 findings2 critical · 2 high 12 findings: 2 critical, 2 high, 4 medium, 4 low
  2. Naming Credits

    18 findings 18 findings: 1 medium, 17 low

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.

Get a quote