The team of AsyncArt contracted byterocket to conduct a smart contract audit of the Blueprint contract for AsyncArt. AsyncArt is developing and providing a novel platform, allowing artists and users to experience art uniquely through modifiable NFTs. Art pieces are separated into master layers and controller layers, which users may control to alter the appearance of the NFT. This newest contract “allows for the creation of non-fungible tokens (NFTS) using the ERC721 standard. A blueprint is then a series of NFT artworks that are static images generated from provably random layers. An artist can create a blueprint of a series of pieces and sell them using this smart contract. Fans of the artist can then purchase a provably random artwork related to the blueprint.”
The functionality is contained in the Blueprint.sol file, with ERC721 (NFT), Access Right, and Merkle Proof-related imports.
The team of byterocket reviewed and audited the above smart contracts in the course of this audit. We started on the 15th of November and finished on the 4th of December.
The audit included the following services:
byterocket gained access to the code via their private Github Repository. We initially based the audit on the master branch’s state on November 26th, 2021 (commit hash 99e71e49c98b9da1d8b9a140bfd647a34b061970). Subsequent fixes and further changes up until the commit hash 422102fd0cfe512175e6f309ae37f4836e63d0b4 from December 4th have been included in this audit.
We conducted a manual multi-pass code review of the smart contracts mentioned in section (1). Three different people went through the smart contract independently and compared their results in multiple concluding discussions.
These contracts are written according to the latest standards used within the Ethereum community and the Solidity community’s best practices. The naming of variables is very logical and understandable, which results in the contract being useful to understand. The code is very well documented and up to the latest standards.
On the code level, we found no bugs or flaws. One prior finding of medium severity listed below was correctly fixed during the course of this audit. A further check with multiple automated reviewing tools (MythX, Slither, Manticore, and different fuzzing tools) did not find any additional bugs besides some common false positives.
The idea of this function is to define a new address as the minter address, comparable to the updatePlatformAddress() function, that is defining a new platform address. The platform uses the DEFAULT_ADMIN_ROLE - the minter uses the MINTER_ROLE.
In this case, however, the new minter receives the MINTER_ROLE (line 587) but the old minter never loses their minting rights and instead is being revoked their DEFAULT_ADMIN_ROLE (which they probably do not possess).
We believe, that this is a typo and line 600 should say:
We strongly advise the team to fix this before deployment, in order to prevent the old minter address from keeping the minting rights forever and a wrong access right being removed from them.
Update
The function was updated to revoke the correct role from the old minter address. Fixed via commit efc395912eb2b9eba0158392d6cfdbd275e2f59c.
Part of our audits are also analyses of the protocol and its logic. A team of three auditors went through the implementation and documentation of the implemented protocol.
We went through all of the provided documentation, tests, and contracts in a very detailed manner. The general description of the protocol is very well made, it’s very easy to understand how each function is supposed to work and what it implements.
We were not able to discover any problems in the protocol implemented in the smart contract.
As per our testing strategy, we deploy audited smart contracts (if requested by the client) onto a testnet to verify the implementation’s functionality. We usually deploy simple smart contracts to a local Ganache instance, which is sufficient for most cases. In this case, given the contracts’ complexity, we wanted to ensure no Ganache-related coverups of the contracts’ misbehavior. We created two testnets: a geth-based one and a parity/openethereum-based one. All of our tests have been executed on both testnets without any difference in the results. We were able to use the contracts as intended and could not maliciously game the protocol in practice.
We used fuzzing tools that generate random and semi-random inputs and interact with the contracts, trying to produce any unforeseen states within the contracts, especially the treasury contract. Throughout our tests, we were not able to create or observe any issues or problems. The contract behaved as expected and reverted correctly, given wrong inputs. No unforeseen states occurred during our fuzz-tests.
During our code review (which was done manually and automated), we found no bugs or flaws. One prior finding of medium severity listed in section 2.1 was correctly fixed during the course of this audit. . Our automated systems and review tools did not find any additional ones.
The protocol review and analysis did neither uncover any game-theoretical nature problems nor any other functions prone to abuse.
During our multiple deployments to various local testnets, we haven’t been able to find any additional problems or unforeseen issues.
In general, we are delighted with the overall quality of the code and its documentation.
As of the date of publication, the information provided in this report reflects the presently held understanding of the auditor’s knowledge of security patterns as they relate to the client’s contract(s), assuming that blockchain technologies, in particular, will continue to undergo frequent and ongoing development and therefore introduce unknown technical risks and flaws. The scope of the audit presented here is limited to the issues identified in the preliminary section and discussed in more detail in subsequent sections. The audit report does not address or provide opinions on any security aspects of the Solidity compiler, the tools used in the development of the contracts or the blockchain technologies themselves, or any issues not specifically addressed in this audit report.
The audit report makes no statements or warranties about the utility of the code, safety of the code, suitability of the business model, investment advice, endorsement of the platform or its products, the legal framework for the business model, or any other statements about the suitability of the contracts for a particular purpose, or their bug-free status.
To the full extent permissible by applicable law, the auditors disclaim all warranties, express or implied. The information in this report is provided “as is” without warranty, representation, or guarantee of any kind, including the accuracy of the information provided. The auditors hereby disclaim, and each client or user of this audit report hereby waives, releases and holds all auditors harmless from, any and all liability, damage, expense, or harm (actual, threatened, or claimed) from such use.
We store our public audit reports on IPFS; a peer-to-peer network called the "Inter Planetary File System". This allows us to store our reports in a distributed network instead of just a single server, so even if our website is down, every report is still available.
The IPFS Hash, a unique identifier of the report, is signed on-chain by both the client and us to prove that both sides have approved this audit report. This signing mechanism allows users to verify that neither side has faked or tampered with the audit.