After a line by line manual analysis and automated review, Guardian has concluded that:
- Published
- Language
- Solidity
- Chains
- Ethereum
- Sector
- NFTs
- 0 Critical
- 0 High
- 1 Medium
- 17 Low
- 0 Informational
Scope
Overview
After a line by line manual analysis and automated review, Guardian has concluded that:
- NFTR’s smart contracts have a LOW RISK SEVERITY
- NFTR’s smart contracts have an ACTIVE OWNERSHIP
- Important owner/tempAdmin privileges –
updateProtocolFeeRecipient,shutOffAssignments,reduceNamingCredits,setRNMAddress,shutOffFeeRecipientUpdates,addAssignerCredits,nullAssignerCredits,shutOffAssignerAssignments,transferTempAdmin - NFTR’s smart contract owner has multiple “write” privileges. Centralization risk correlated to the active ownership is LOW
Findings 18
-
NMC-1 Low Centralization Risk Centralization / Privilege Resolved
Description
tempAdminhas the ability to essentially mint unlimited naming credits (further discussed on NMC-2), as well as control over numerous functions which could negatively affect the rest of the protocol:setRNMAddress,shutOffFeeRecipientUpdates,addAssignerCredits,nullAssignerCredits,shutOffAssignerAssignments,transferTempAdmin.Recommendation
Ensure
tempAdminis a multi-sig.Resolution
NFTR Team: -
tempAdminwill be a multi-sig. -
NMC-2 Medium Weak Tokenomics Protection Tokenomics / Privilege Resolved
Description
The
MAX_ASSIGNER_CREDITSandMAX_CREDITS_ASSIGNEDoffer little to no protection for the protocol tokenomics.The
MAX_ASSIGNER_CREDITScan be easily circumvented by simply calling theaddAssignerCreditsmultiple times.The
MAX_CREDITS_ASSIGNEDcan be easily circumvented by calling theassignNamingCreditsfunction multiple times or callingassignNamingCreditsBulkwith auserlist that contains the same address multiple times.Therefore it is relatively easy for the
tempAdminandassignersto manipulate the tokenomics of the project, potentially creating unlimited naming credits or allowing a particular address to accumulate more than the intended amount of naming credits.Recommendation
Base the
MAX_ASSIGNER_CREDITSandMAX_CREDITS_ASSIGNEDon the assigner/user balance and possibly introduce a hard cap on the number ofnamingCreditsthat can be in circulation to prevent an unexpected amount ofnamingCreditsbeing created.Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-3 Low Zero Address Checks Best Practices Resolved
Description
The
constructor,transferTempAdmin, andupdateProtocolFeeRecipientfunctions all assign important address contract variables without ensuring any of them are not the zero address.Recommendation
Evaluate whether or not each of these addresses can be assigned to the zero/dead address and add prohibiting requires statements accordingly.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-4 Low Superfluous Code Optimization Resolved
Description
The
currencyQuantityparameter is required to be equal tonumberOfCredits *nftrAddress.namingPriceEther()in theBuyWithEth.YEScase, and equal tonumberOfCredits *nftrAddress.namingPriceRNM()in theBuyWithEth.NOcase.Therefore all subsequent computations of
numberOfCredits * nftrAddress.namingPriceEther()ornumberOfCredits * nftrAddress.namingPriceRNM()can be replaced with thecurrencyQuantity.Recommendation
Implement the above simplifications.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-5 Low Superfluous Code Optimization Resolved
Description
In
buyNamingCredits, therequirestatements inside of the firstifstatement can be moved into theifstatement below. This way thebuyWithEthtype can be checked just once.Recommendation
Implement the above simplifications.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-6 Low Unnecessary Require Statements Optimization Acknowledged
Description
There are several
requirestatements that appear directly before atransferFromfunction call or-=operator that would otherwise revert without the presence of therequirestatement.Recommendation
Remove the unnecessary
requirestatements and optionally replace each-=with a.subalternative if the revert messages are necessary.Resolution
NFTR Team: - Acknowledged, but left as is for simplicity.
-
NMC-7 Low Unnecessary Casting Optimization Resolved
Description
The
nftrAddressandrnmAddressvariables are stored asINFTRegistryandIRNMtypes in the contract, however they are often redundantly cast toINFTRegistryandIRNMtypes in thebuyNamingCreditsfunction.Recommendation
Remove the redundant casts.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-8 Low Typo Typo Resolved
Description
On line 120, “buy” is misspelled as “by”.
Recommendation
Replace “by” with “buy” in the comment.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-9 Low Default Value Assignment Optimization Resolved
Description
On line 195 the
uintvariable i is initialized to the default value of 0.Recommendation
Remove the unnecessary assignment.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-10 Low Cache Array Length Optimization Resolved
Description
Caching the array length outside a
forloop saves reading it on each iteration.Recommendation
Declare a
lenvariable and use it as the upper bound in theforloop.Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-11 Low Uint Comparisons Optimization Resolved
Description
When dealing with unsigned integer types, comparisons with
!= 0are cheaper than with> 0.Recommendation
Replace the
assigners[msg.sender] > 0check withassigners[msg.sender] != 0.Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-12 Low Storage Modifiers Optimization Resolved
Description
In
assignNamingCreditsBulktheaddress[] memory userandaddress[] memory numberOfCreditsparameters are never altered and therefore can be declaredcalldata.Recommendation
Declare the variables
calldata.Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-13 Low Shorten Revert Strings Optimization Acknowledged
Description
Throughout the contract revert strings that are longer than 32 bytes are used.
Recommendation
Shorten revert strings to less than 32 bytes to save on gas.
Resolution
NFTR Team: - Acknowledged, but left as is for simplicity.
-
NMC-14 Low Access Modifiers Optimization Resolved
Description
Throughout the contract there are several require statements that assert the
msg.senderis thetempAdmin. Theserequirestatements can be deduplicated into a singleonlyTempAdminmodifier that can be used on each of these functions.Recommendation
Create an
onlyTempAdminmodifier and apply it to each of these functions.Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-15 Low Duplicate Reads Optimization Resolved
Description
In
assignNamingCreditsBulkthenumberOfCredits[i]value is read up to five times upon each iteration. Declare auint creditNumoutside of theforloop and cache thenumberOfCreditsvalue in it upon each iteration.Recommendation
Implement the above suggestion.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-16 Low For-Loop Increment Optimization Resolved
Description
Because the
userarray’s length is bound byMAX_BULK_ASSIGNMENT, there is no risk of overflow. To reduce bytecode, use an unchecked block in the loop to increment.Recommendation
Implement the above suggestion.
Resolution
NFTR Team: - The suggested changes were implemented.
-
NMC-17 Low Custom Reverts Optimization Acknowledged
Description
Since Solidity v0.8.4, the more gas-efficient custom-errors have been introduced. They allow for passing dynamic data in the error and remove costly and repeated string error messages.
Recommendation
Consider replacing
requirestatements with custom errors.Resolution
NFTR Team: - Acknowledged, but left as is for simplicity.
-
NMC-18 Low Visibility Modifiers Visibility Modifiers Resolved
Description
The functions
setRNMAddressandupdateProtocolFeeRecipientare declared aspublicbut are never called from within the contract.Recommendation
Modify the visibility from
publictoexternal.Resolution
NFTR Team: - The suggested changes were implemented.
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.
