Meta Travelers - Smart Contract Audit Report

Summary

Meta Travelers Audit Report Meta Travelers is a new non-fungible token with multiple minting periods and randomly determined metadata.

For this audit, we reviewed the MetaTravelers contract provided to us at commit 7e7269bda7c75fb856d2569605ef7a3d3cae7df9s on the team's private GitHub.

Notes on the Contract:
  • The maximum total supply of MetaTravelers NFTs is 7777.
  • Users are able to burn any of their NFTs reducing the total supply.
  • The cost of minting an NFT during any stage is 0.123 ETH.

  • There is toggleable Early Adopter and Presale minting that allows approved users to mint.
  • While the Early Adopter stage is enabled, anyone on the Early Adopter list can mint up to 5 NFTs. The maximum mintable NFTs via Early Adopter stage is 1665.
  • While the Presale stage is enabled, anyone on the Presale list can mint up to 3 NFTs, as long as their total count of NFTs including those minted in the Early Adopter stage is no more than 3. The maximum mintable NFTs increases to 3330 via the Presale stage.
  • While the Mint Pass stage is enabled, anyone with a Mint Pass is able to redeem the Mint Pass for 1 NFT. The maximum mintable NFTs increases to 5661 via the Mint Pass stage.
  • While the Public Sale stage is enabled, anyone is able to mint up to 3 NFTs at a time. The maximum mintable NFTs increases to the maximum amount of 7777 via the Public Sale stage.
  • NFT metadata that contains information about the NFT is stored using an off-chain URI endpoint.
  • NFTs are minted but not indexed; the random starting index will determine the metadata that is assigned to the NFT.
  • Chainlink VRF is used to generate random numbers to select a starting index. This is the industry standard and is resistant to manipulation.
  • LINK will need to be held in the contract to pay the fee associated with the randomness request.

  • The owner is able to mint themselves any amount of NFTs at any time.
  • The owner is able to toggle any of the minting functionality at any time.
  • The owner is able to add any address to the Early Adopters and Presale list at any time.
  • The owner is able to give users any amount of Mint Passes at anytime.
  • The owner is able to change the URI endpoint at any time.
  • The owner can withdraw all ETH from the contract at any time.
  • The owner can pause and unpause the contract at anytime which prevents any transfer, minting, and burning functionality.

  • The contract is ERC721 compliant; all standard functionality is present.
  • As the project is implemented with solidity version ^0.8.0, it is protected from overflows.
Audit Findings Summary
  • No external threats were identified.
  • Ensure trust in the team as they have considerable control within the ecosystem.
  • Date: November 1st, 2021.
  • Updated: November 1st, 2021 to address multiple improvements.
Resolved Issues
  • The team worked with us to implement changes related to gas optimization.
  • The team has communicated their plan to generate the random data after NFTs have been minted in line with our recommendation.
  • Restricted the call to Chainlink VRF to only the owner to prevent concurrent requests for randomness.
  • Audit Results

    Vulnerability CategoryNotesResult
    Arbitrary Storage WriteN/APASS
    Arbitrary JumpN/APASS
    Delegate Call to Untrusted ContractN/APASS
    Dependence on Predictable VariablesN/APASS
    Deprecated OpcodesN/APASS
    Ether ThiefN/APASS
    ExceptionsN/APASS
    External CallsN/APASS
    Flash LoansN/APASS
    Integer Over/UnderflowN/APASS
    Multiple SendsN/APASS
    OraclesN/APASS
    SuicideN/APASS
    State Change External CallsN/APASS
    Unchecked RetvalN/APASS
    User Supplied AssertionN/APASS
    Critical Solidity CompilerN/APASS
    Overall Contract Safety PASS

    MetaTravelers Graph

    MetaTravelers

    
     ($) = payable function
     # = non-constant function
    
      +  Context 
        - [Int] _msgSender
        - [Int] _msgData
    
     +  Ownable (Context)
        - [Pub] Constructor #
        - [Pub] owner
        - [Pub] renounceOwnership #
           - modifiers: onlyOwner
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
        - [Prv] _setOwner #
    
     + [Lib] Counters 
        - [Int] current
        - [Int] increment #
        - [Int] decrement #
        - [Int] reset #
    
     + [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
    
     + [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] IERC721Receiver 
        - [Ext] onERC721Received #
    
     + [Int] IERC721Metadata (IERC721)
        - [Ext] name
        - [Ext] symbol
        - [Ext] tokenURI
    
     + [Lib] Address 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Int] functionDelegateCall #
        - [Int] functionDelegateCall #
        - [Int] verifyCallResult
    
     + [Lib] Strings 
        - [Int] toString
        - [Int] toHexString
        - [Int] toHexString
    
     +  ERC165 (IERC165)
        - [Pub] supportsInterface
    
     +  ERC721 (Context, ERC165, IERC721, IERC721Metadata)
        - [Pub] Constructor #
        - [Pub] supportsInterface
        - [Pub] balanceOf
        - [Pub] ownerOf
        - [Pub] name
        - [Pub] symbol
        - [Pub] tokenURI
        - [Int] _baseURI
        - [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] _approve #
        - [Prv] _checkOnERC721Received #
        - [Int] _beforeTokenTransfer #
    
     +  Pausable (Context)
        - [Pub] Constructor #
        - [Pub] paused
        - [Int] _pause #
           - modifiers: whenNotPaused
        - [Int] _unpause #
           - modifiers: whenPaused
    
     +  ERC721Pausable (ERC721, Pausable)
        - [Int] _beforeTokenTransfer #
    
     + [Int] IERC721Enumerable (IERC721)
        - [Ext] totalSupply
        - [Ext] tokenOfOwnerByIndex
        - [Ext] tokenByIndex
    
     +  ERC721Enumerable (ERC721, IERC721Enumerable)
        - [Pub] supportsInterface
        - [Pub] tokenOfOwnerByIndex
        - [Pub] totalSupply
        - [Pub] tokenByIndex
        - [Int] _beforeTokenTransfer #
        - [Prv] _addTokenToOwnerEnumeration #
        - [Prv] _addTokenToAllTokensEnumeration #
        - [Prv] _removeTokenFromOwnerEnumeration #
        - [Prv] _removeTokenFromAllTokensEnumeration #
    
     +  ERC721Burnable (Context, ERC721)
        - [Pub] burn #
    
     + [Int] LinkTokenInterface 
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] balanceOf
        - [Ext] decimals
        - [Ext] decreaseApproval #
        - [Ext] increaseApproval #
        - [Ext] name
        - [Ext] symbol
        - [Ext] totalSupply
        - [Ext] transfer #
        - [Ext] transferAndCall #
        - [Ext] transferFrom #
    
     +  VRFRequestIDBase 
        - [Int] makeVRFInputSeed
        - [Int] makeRequestId
    
     +  VRFConsumerBase (VRFRequestIDBase)
        - [Int] fulfillRandomness #
        - [Int] requestRandomness #
        - [Pub] Constructor #
        - [Ext] rawFulfillRandomness #
    
     +  MetaTravelers (ERC721Enumerable, ERC721Pausable, ERC721Burnable, VRFConsumerBase, Ownable)
        - [Pub] Constructor #
           - modifiers: ERC721,VRFConsumerBase
        - [Ext] setBaseTokenURI #
           - modifiers: onlyOwner
        - [Ext] addToEarlyAdopterList #
           - modifiers: onlyOwner
        - [Ext] addToPreSaleList #
           - modifiers: onlyOwner
        - [Ext] addToMintPassList #
           - modifiers: onlyOwner
        - [Ext] toggleEarlyAdopter #
           - modifiers: onlyOwner
        - [Ext] togglePreSale #
           - modifiers: onlyOwner
        - [Ext] toggleMintPassSale #
           - modifiers: onlyOwner
        - [Prv] _baseMint #
        - [Ext] earlyAdopterMint ($)
        - [Ext] preSaleMint ($)
        - [Ext] mintPassMint ($)
        - [Ext] publicSaleMint ($)
        - [Pub] reserveMetaTravelers #
           - modifiers: onlyOwner
        - [Pub] setProvenanceHash #
           - modifiers: onlyOwner
        - [Pub] setStartingIndex #
        - [Int] fulfillRandomness #
        - [Pub] withdraw #
           - modifiers: onlyOwner
        - [Pub] tokenURI
        - [Ext] pause #
           - modifiers: onlyOwner
        - [Ext] unpause #
           - modifiers: onlyOwner
        - [Pub] supportsInterface
        - [Int] _beforeTokenTransfer #