NaaS - Audit Report
OMNI-PSI is building a new NFT's-as-a-Service platform to faciliate asset exchanges and distributions for creators and royalty recipients in a decentralized manner to be used in the context of a real estate NFT marketplace.
We reviewed the NaaS contracts at commit 0f4848220239146b85869666fe8ef06bc7d32d1d on the team's private GitHub repository.
We previously reviewed the project team's launchpad platform here.
Notes on Individual Contracts:
NaaS and NaaSPrivate Contracts:
- The NaaS contract allows anyone to mint ERC1155 NFTs at any time, while only approved minters may use the NaaSPrivate contract to mint.
- On minting NFTs, creator information and royalty information is stored in order to perform proper distributions upon exchanging.
- Users can specify multiple creator addresses and multiple addresses to receive royalties.
- The contract uses various means to ensure the validity of the creator information supplied by the user. Only one of the following checks is needed in order to pass:
- Verify the user is the creator themselves.
- Ensure that the user serves as a registered proxy address for the creator.
- In the event that the creator address is a contract, call its isValidSignature function and ensure it returns the 'magic value' specified by the NaaS contract.
- Verify that the user is the address that signed the hashed mint data using the signature provided.
- Users who choose to mint or transfer NFTs to a contract must ensure that the onERC1155Received function is implemented correctly, or the mint will fail.
- NFTs can be minted in batches for gas saving purposes.
- Anyone can burn their own NFTs or NFTs they are approved to operate at any time.
- Users who receive royalties on NFT purchases are able to change the address that is set to receive their royalties at any time.
- The owner is able to set the Proxy Registry contract address at any time, but must wait 7 days before it can be applied.
- Once the wait time has passed, the owner must manually apply the change in order for it to take effect.
- The owner is able to reset the Proxy Registry contract address to the 0x00 address at any time.
- Anyone can use this contract to create and register a new proxy contract which is used to execute calls that are made throughout the platform on behalf of the user.
- A user can create and register a new proxy contract at any time, overriding any existing proxy contract associated with the user.
- Anyone can register create and register a new proxy contract on behalf of another user without any approval.
- A user can transfer the ownership of their existing proxy contract to any user that does not have an existing proxy contract associated with them.
- Only the user who owns the proxy or an address authorized by the Registry, as long as access has not been revoked, can use the proxy contract to execute calls.
- A proxy owner can revoke access to addresses authorized by the Registry at any time.
- The Registry can authorize any address to operate on users' proxy contracts at any time, but can only be activated after the 2-week delay period has elapsed.
- The Registry can revoke this authorization for any address at any time.
- The owner can swap out the implementation code used for generating the proxy contracts at any time.
NaaSAtomicizer and NaaSStatic Contracts:
- This contract is used to perform asset exchanges between users.
- Users can approve Orders they are authorized to approve as specified in the Order, and can also adjust the Order fill value for each Order as necessary.
- The contract executes Orders between two parties one after the other and within the same transaction so that if any validations fail, no exchange of assets will occur.
- The parameters of each Order are validated to ensure that each of the three conditions are met: (1) the Order has not already been fully filled, (2) the Order's static target address exists, and (3) the time at which the transaction is executed is between the listing time and the expiration time.
- The authorization of each Order is validated to ensure that at least one of the following five conditions is met: (1) the Order is partially filled, (2) the user is the maker of the Order, (3) the maker has already approved the Order, (4) the maker is a contract and we can validate the signature against the hash, or (5) we can validate that the signer matches the maker's address.
- After the Orders are successfully validated, the call data corresponding to each Order is executed using the makers' proxy contracts, and the fill values for each Order are updated.
- Users can use the contract to easily mint ERC1155 tokens, or transfer ETH, ERC20 tokens, ERC721 tokens, and ERC1155 tokens to facilitate exchanges.
- The contract takes a portion of the transferred funds as a protocol fee, and another portion is distributed among royalty receivers as needed. The total percentage of fees taken as royalties cannot exceed 50%.
- The owner is able to set the Royalties Registry address, the default fee receiver address, and the fee receiver wallet address for any token address at any time.
- The owner is able to set the protocol fee to any value at any time.
- These contracts are used to assist in executing transactions with NaaSExchange.
- The NaaSAtomicizer presents a function that can be used to execute multiple transactions in order in an atomic fashion. If any of the calls within the function fail, the entire function reverts.
- The NaaSStatic contract provides methods for executing static calls to support transfers on the NaaSExchange platform involving ERC20, ERC721, ERC1155 tokens. This contract provides proper validation checks to ensure that these functions are not called erroneously.
- Any address currently registered as the sole creator of an ERC1155 NFT can use this contract to set the creator address associated with the NFT in the platform to any address at any time.
- Anyone can use this contract to set multiple creators of an existing ERC1155 NFT; a signature is required from each of the previous creators in order to set new creators, and each new creator address must be verified as the signer of the new ERC1155Creators data supplied by the user.
- Users can specify differing ownership percentages for each creator, but the the sum of the percentages must be exactly 100%.
- This contract can also be used by external contracts to store creator data for an NFT and set the corresponding ownership percentages.
General notes across all contracts:
- This contract is used to set royalty receivers and corresponding distribution percentages for an ERC1155 NFT Collection or a single ERC1155 NFT within the platform.
- When supplying distribution percentages for a Collection, the sum of percentages cannot exceed 100%. When setting distribution percentages for a single NFT, the sum of the percentages cannot exceed 50%.
- This contract can also be used to associate a Royalties Provider address with any token address.
- Royalties information is only intended to be set by the owner of the asset, but the owner of the platform is also able to set royalties information for any NFT or NFT Collection at any time with this contract.
- The contract also provides a function that anyone can call to retrieve the royalty information for any single NFT. The function will query the data in the contract in the following order:
- Royalty information for the single NFT.
- Royalty information for the NFT's Collection.
- Royalty information for the token Royalty Provider.
- Royalty information for the single NFT on the NaaS contract.
- The first source to return a non-empty value will be used as the royalty information. In the event that royalty information is not currently set in the contract for the single NFT or the NFT's Collection, the contract will set the royalty information for the NFT using the next available source of data.
- Excellent structuring of logic to prevent reentrancy attacks.
- The NaaS and NaaSPrivate contracts comply with the ERC1155 Multi-Token Standard.
- The Exchange platform and all its components are based on the Wyvern Protocol v3.1.
- Some functions could have been declared external and some state variables could have been declared constant for further gas optimization.
- The contracts are implemented with Solidity v0.8.x, and thus are protected from overflows.
Audit Findings Summary:
- No security issues from outside attackers were identified.
- Ensure trust in the project team as they have considerable control in the ecosystem and can alter any creator's royalty address at any time.
- Although the team can upgrade many of the platform's contracts at any time, note that no assets are ever stored within the exchange.
- Date: November 18th, 2021.
External Threat Results
|Arbitrary Storage Write||N/A||PASS|
|Delegate Call to Untrusted Contract||N/A||PASS|
|Dependence on Predictable Variables||N/A||PASS|
|State Change External Calls||N/A||Pass|
|User Supplied Assertion||N/A||PASS|
|Critical Solidity Compiler||N/A||PASS|
|Overall Contract Safety||PASS|
Contract Source Summary and Visualizations