Audit · firm’s term: audit report
QuillAudits reviewed NFTs2Me on 26 Feb 2024: 7 findings, 0 critical; 1 marked fixed, 6 open.
Report hosted on quillaudits.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 0 | 0 |
| Medium | 0 | 0 | 0 |
| Low | 6 | 0 | 1 |
The project is expected to be deployed on the zkSync network as well. However, the current implementation of createCrossCollection will not work as intended on zkSync due to CREATE3.According to zkSync Era’s docs, it states that create cannot be used for arbitrary code unknown to the compiler.
multicall() and multicallN2M_001Taw5z() are using delegatecall() in the loop. Here any native token balance that the contract has, can be used by using delegate calls and not sending enough value to execute the transaction but instead using the value/native token balance from the contract.Example: User performs multicall that takes some value from the contract. Let’s say multicall to execute createNewDynamic() 2 times. which will deploy a contract and will call the function specified in the data with the msg.value provided. But because of the same msg.value will be reused multiple times while using delegateCall() in the loop, the user may send the value required for first createNewDynamic() call and for the next call, the value stored in the contract i.e N2MFactory contract’s balance will be used.
Function create3() is not returning the value of the deployed contract.
Currently the verifying contract’s address is not getting included while creating hash on L247 with ECDSA.toEthSignedMessageHash(). In the case where the team decides to deprecate the current contract because of some reason, and after deploying the new contract. The same used signature can be reused on that contract to create a new collection on behalf of the owner/signer. (Currently signature verification is only getting used to deploy the contract, so even though any bad actor can use the signature again on a different contract version on the same chain, this directly creates no risk to the signer because the worst case possible here would be to create the another contract on behalf of the original owner/signer. Still its good idea to take care of it.) Additionally, this function is not checking that the nonce is different for the specific owner address, which creates the risk of using the same signature again on the same factory contract, but in this case, the deployment process will revert as the contract is already present on that address if someone replays it.
The caller can send msg.value to some functions if required for transaction execution. It can happen that while executing a call with multicallMulticollection(), more msg.value is getting sent than what is required. In these types of cases, the remaining value can be sent back to the msg.sender.
delegatedCreation() function verifies the signed signature for the function call, which allows executing creation transaction on behalf of others. Currently, theres no timestamp getting used to check if the signature is expired or not.Adding an expiry timestamp in the signature verification logic will make sure that the signature is getting used within the expected timeframe (i.e. before it expires).
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (2)
350 projects reviewed · 459 reports · latest Apr 2025
See QuillAudits’s auditsSomething wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us