Project3333 - Audit Report
Summary
Project3333 is a building a new NFT collection with a presale and public sale on the Ethereum blockchain.
Overview of the Contract:Audit Findings Summary
- This contract is used to facilitate a presale and a public sale for the Project3333 NFT.
- There is a limit to the total amount of NFTs that can be minted during the presale and during the public sale.
- There is a limit on the amount of NFTs that can be minted per address during the presale and during the public sale.
- There may be different pricing available for NFTs purchased during the presale and during the public sale.
- While the presale is active, whitelisted users can purchase NFTs at the presale price as long as the supply limits have not been met.
- While the public sale is active, anyone can purchase NFTs at the public sale price as long as the supply limits have not been met.
- Users must exercise caution when providing ETH to purchase NFTs to ensure that the correct amount is used, as the contract will not return any excess ETH to the user.
- After the NFTs are purchased, the user will need to trigger a claim in order to mint their NFTs.
- Users are not able to use contracts to purchase and claim NFTs; all purchases and claim requests must be originated by externally-owned accounts (EOAs).
- The owner can exceed the supply limitations that are in place for all other users and mint an unlimited amount of NFTs to any address.
- The owner can limitlessly mint only before the sale has begun, or after all purchased NFTs have been claimed; in the event that the owner is minting NFTs to an address that is a contract, the receiving contract must have implemented the onERC721Received() function in order to successfully receive the NFT.
- The owner can set the mint price for both the presale and the public sale to any value at any time.
- The owner can set the total amount that can be minted during both the presale and the public sale to any value at any time.
- The owner can set the amount that can be minted per address during both the presale and the public sale to any value at any time.
- The owner can enable or disable both the presale and the public sale at any time.
- The owner can set the start time for both the presale and the public sale to any value at any time.
- The owner can add or remove any address from the presale whitelist at any time.
- The owner can withdraw any ETH in the contract balance at any time.
- The owner can set the base URI value to any value at any time.
- The contract uses ReentrancyGuard to protect relevant functions from re-entrancy attacks, and to ensure that contracts cannot use the system.
- The contract complies with the ERC-721 standard.
- Although the SafeMath library is utilized, the contract is deployed with Solidity v0.8.9 which has built-in overflow protection. SafeMath can be safely removed to reduce contract size and increase gas savings. Since the contract is already deployed, this is merely informational.
- No security threats from outside attackers were identified.
- Ensure trust in the team as they have notable control in the ecosystem.
- Date: December 3rd, 2021
External Threat Results
Vulnerability Category | Notes | Result |
---|---|---|
Arbitrary Storage Write | N/A | PASS |
Arbitrary Jump | N/A | PASS |
Centralization of Control | The owner can mint an unlimited amount of NFTs. | WARNING |
Delegate Call to Untrusted Contract | N/A | PASS |
Dependence on Predictable Variables | N/A | PASS |
Deprecated Opcodes | N/A | PASS |
Ether Thief | N/A | PASS |
Exceptions | N/A | PASS |
External Calls | N/A | PASS |
Flash Loans | N/A | PASS |
Integer Over/Underflow | N/A | PASS |
Multiple Sends | N/A | PASS |
Oracles | N/A | PASS |
Suicide | N/A | PASS |
State Change External Calls | N/A | PASS |
Unbounded Loops | N/A | PASS |
Unchecked Retval | N/A | PASS |
User Supplied Assertion | N/A | PASS |
Critical Solidity Compiler | N/A | PASS |
Overall Contract Safety | PASS |
($) = payable function
# = non-constant function
+ Context
- [Int] _msgSender
- [Int] _msgData
+ [Int] IERC165
- [Ext] supportsInterface
+ [Int] IERC721 (IERC165)
- [Ext] balanceOf
- [Ext] ownerOf
- [Ext] safeTransferFrom #
- [Ext] transferFrom #
- [Ext] approve #
- [Ext] getApproved
- [Ext] setApprovalForAll #
- [Ext] isApprovedForAll
- [Ext] safeTransferFrom #
+ [Int] IERC721Metadata (IERC721)
- [Ext] name
- [Ext] symbol
- [Ext] tokenURI
+ [Int] IERC721Enumerable (IERC721)
- [Ext] totalSupply
- [Ext] tokenOfOwnerByIndex
- [Ext] tokenByIndex
+ [Int] IERC721Receiver
- [Ext] onERC721Received #
+ ERC165 (IERC165)
- [Pub] #
- [Pub] supportsInterface
- [Int] _registerInterface #
+ [Lib] SafeMath
- [Int] tryAdd
- [Int] trySub
- [Int] tryMul
- [Int] tryDiv
- [Int] tryMod
- [Int] add
- [Int] sub
- [Int] mul
- [Int] div
- [Int] mod
- [Int] sub
- [Int] div
- [Int] mod
+ [Lib] Address
- [Int] isContract
- [Int] sendValue #
- [Int] functionCall #
- [Int] functionCall #
- [Int] functionCallWithValue #
- [Int] functionCallWithValue #
- [Int] functionStaticCall
- [Int] functionStaticCall
- [Int] functionDelegateCall #
- [Int] functionDelegateCall #
- [Prv] _verifyCallResult
+ [Lib] EnumerableSet
- [Prv] _add #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] add #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
+ [Lib] EnumerableMap
- [Prv] _set #
- [Prv] _remove #
- [Prv] _contains
- [Prv] _length
- [Prv] _at
- [Prv] _tryGet
- [Prv] _get
- [Prv] _get
- [Int] set #
- [Int] remove #
- [Int] contains
- [Int] length
- [Int] at
- [Int] tryGet
- [Int] get
- [Int] get
+ [Lib] Strings
- [Int] toString
- [Int] toHexString
- [Int] toHexString
+ ERC721 (Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable)
- [Pub] #
- [Pub] balanceOf
- [Pub] ownerOf
- [Pub] name
- [Pub] symbol
- [Pub] tokenURI
- [Pub] baseURI
- [Pub] tokenOfOwnerByIndex
- [Pub] totalSupply
- [Pub] tokenByIndex
- [Pub] approve #
- [Pub] getApproved
- [Pub] setApprovalForAll #
- [Pub] isApprovedForAll
- [Pub] transferFrom #
- [Pub] safeTransferFrom #
- [Pub] safeTransferFrom #
- [Int] _safeTransfer #
- [Int] _exists
- [Int] _isApprovedOrOwner
- [Int] _safeMint #
- [Int] _safeMint #
- [Int] _mint #
- [Int] _burn #
- [Int] _transfer #
- [Int] _setTokenURI #
- [Int] _setBaseURI #
- [Prv] _checkOnERC721Received #
- [Int] _approve #
- [Int] _beforeTokenTransfer #
+ Ownable (Context)
- [Pub] #
- [Pub] owner
- [Pub] renounceOwnership #
- modifiers: onlyOwner
- [Pub] transferOwnership #
- modifiers: onlyOwner
+ ReentrancyGuard
- [Pub] #
+ three333 (ERC721, Ownable, ReentrancyGuard)
- [Pub] #
- modifiers: ERC721
- [Ext] tokensOfOwner
- [Pub] exists
- [Pub] isPresaleLive
- [Pub] isPublicSaleLive
- [Ext] setMintPrice #
- modifiers: onlyOwner
- [Ext] setPresaleMintPrice #
- modifiers: onlyOwner
- [Ext] setMaxNftSupply #
- modifiers: onlyOwner
- [Ext] setMaxPresaleSupply #
- modifiers: onlyOwner
- [Ext] setMaxPresaleToMint #
- modifiers: onlyOwner
- [Ext] setMaxPublicToMint #
- modifiers: onlyOwner
- [Ext] reserveNfts #
- modifiers: onlyOwner
- [Ext] setBaseURI #
- modifiers: onlyOwner
- [Ext] updatePresaleState #
- modifiers: onlyOwner
- [Ext] updatePublicSaleState #
- modifiers: onlyOwner
- [Ext] addToPresale #
- modifiers: onlyOwner
- [Ext] removeToPresale #
- modifiers: onlyOwner
- [Ext] isInWhitelist
- [Ext] doPresale ($)
- modifiers: isHuman,nonReentrant
- [Ext] doPublic ($)
- modifiers: isHuman,nonReentrant
- [Pub] getUserClaimableTicketCount
- [Ext] claimNfts #
- modifiers: isHuman,nonReentrant
- [Ext] withdraw #
- modifiers: onlyOwner