[N-01] The risks of relying on assert() in solidity contracts
In Solidity, the assert() function is meant to handle conditions that should never be false, and if they are, it points to a bug within the contract.
Before Solidity 0.8.0, when assert() is triggered, it consumes all of the remaining gas in a transaction, which differs from the behavior of require() and revert() that return unspent gas.
Even in versions after 0.8.0, it's prudent to minimize the use of assert(). The Solidity documentation suggests that code should never reach a state where assert() is triggered. Instead, for better clarity and understanding of contract failures, developers are advised to utilize require() statements or custom error messages.
By doing so, they can provide a more transparent and user-friendly contract, which aids in identifying and rectifying issues more efficiently.
[N-02] Prefer string.concat() or bytes.concat() to abi.encodePacked
With the release of Solidity version 0.8.4, the language introduced bytes.concat() as a clearer alternative to the abi.encodePacked(< bytes >,< bytes >) method for concatenating byte sequences.
Similarly, Solidity version 0.8.12 brought string.concat(), providing a direct means for string concatenation, sidestepping the abi.encodePacked(< str >,< str >) approach.
Incorporating these recent methods can improve code readability and align your contracts with modern Solidity practices.
Starting with Solidity version 0.8.8, using the override keyword when the function solely overrides an interface function, and the function doesn't exist in multiple base contracts, is unnecessary.
uint48
for time-centric variablesoverride
is unnecessary[N-01] The risks of relying on assert() in solidity contracts
In Solidity, the assert() function is meant to handle conditions that should never be false, and if they are, it points to a bug within the contract.
Before Solidity 0.8.0, when assert() is triggered, it consumes all of the remaining gas in a transaction, which differs from the behavior of require() and revert() that return unspent gas.
Even in versions after 0.8.0, it's prudent to minimize the use of assert(). The Solidity documentation suggests that code should never reach a state where assert() is triggered. Instead, for better clarity and understanding of contract failures, developers are advised to utilize require() statements or custom error messages.
By doing so, they can provide a more transparent and user-friendly contract, which aids in identifying and rectifying issues more efficiently.
482, 571, 828
[N-02] Prefer string.concat() or bytes.concat() to abi.encodePacked
With the release of Solidity version 0.8.4, the language introduced bytes.concat() as a clearer alternative to the abi.encodePacked(< bytes >,< bytes >) method for concatenating byte sequences.
Similarly, Solidity version 0.8.12 brought string.concat(), providing a direct means for string concatenation, sidestepping the abi.encodePacked(< str >,< str >) approach.
Incorporating these recent methods can improve code readability and align your contracts with modern Solidity practices.
43, 72
[N-03] Recommendation to use
uint48
for time-centric variablesFor time-relevant variables,
uint32
might be restrictive as it ends in 2106, potentially posing challenges in the far future.On the other hand, using excessively large types like
uint256
is unnecessary. Thus,uint48
offers a balanced choice for such use cases.29, 75
[N-04] Unresolved TODO comments in code
The presence of TODO comments suggests that certain features might be incomplete or not ready for audit.
It's advisable to address these issues and remove the TODO markers from the code.
458, 462
[N-05] Use of
override
is unnecessaryStarting with Solidity version 0.8.8, using the override keyword when the function solely overrides an interface function, and the function doesn't exist in multiple base contracts, is unnecessary.
24, 35, 46