CryptoBearWatchClub - Smart Contract Audit Report

Audit Summary

CBWC Audit Report CryptoBearWatchClub is a new auction based NFT project with a corresponding ERC20 token and yield earning properties.

For this audit, we reviewed the Arkouda and CryptoBearWatchClub contracts provided to us by the project team.

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: January 14th, 2022.
Updated: January 20th, 2022 to address issues resolved by the team.

Contracts Overview

CryptoBearWatchClub Contract:
  • This contract is used to facilitate a presale and a public sale for the CryptoBearWatchClub NFTs.
  • The maximum total supply of CBWC NFTs is 10,000.
  • While the presale is active, eligible users can each purchase up to an owner-defined maximum amount of NFTs until the maximum total supply has been reached.
  • The contract uses an off-chain generated Merkle tree provided by the owner to store and verify addresses that are eligible to mint during the presale.
  • While the public sale is active, users can each purchase up to 3 NFTs per transaction until the maximum total supply has been reached.
  • CBWC NFT sale prices are determined by a dutch auction with a starting price of 3 ETH in which the price is decreased by 0.1% every 5 minutes until it reaches the floor price of 0.5 ETH.
  • Users can provide any amount of ETH when purchasing NFTs, and any excess ETH is returned to the user.
  • When CBWC NFTs are transferred, the contract calls the updateReward() function on the Arkouda contract which calculates and updates the sender's pending rewards.
  • The owner can withdraw all funds from the contract at any time.
  • The owner can set the start time of the presale and public sale at any time.
  • The owner can toggle the presale and public sale at any time.
  • The owner can change the presale mint limit at any time.
  • The owner can set the Arkouda contract address to any address at any time.
  • The owner can set the root of the Merkle tree at any time, effectively controlling presale eligibility.
  • The owner can set the base URI to any value at any time.
  • The contract complies with the ERC-721 standard.
  • As the contracts are developed with Solidity 0.8.x, they are protected from overflow/underflow attacks.

  • CryptoBearWatchClub.sol - Finding #1 - Informational

    Description: The following state variables can never be modified, but are not declared constant.
    			
    priceDeductionPercentage, startingPrice
    
    Recommendation: We recommend declaring these state variables constant for additional gas savings on each call.
    Resolution: The team has declared these variables constant.
Arkouda Contract:
  • This token is intended to serve as the reward token for users who hold CryptoBearWatchClub NFTs.
  • The total supply of this token is initially set to 0 and is minted as users claim rewards from holding CBWC NFTs.
  • Users can claim their rewards at any time; rewards accrue every second and are based on a reward rate set by the team. Rewards are only calculated for each full 30 day interval.
  • The team may set the reward rate for each NFT to any value as long as the base rate is at least 10 $ARK per month.
  • Only whitelisted addresses can burn their tokens at any time and as a result can reduce the total supply.
  • Alternatively, any user can send their tokens to the 0x..dead address to reduce the circulating supply at any time.
  • The owner can pause and unpause reward claiming functionality at any time.
  • The owner can set the reward start time to any value at any time.
  • The owner can set the reward rate for any token or batch of tokens at any time.
  • The owner can grant any address the ability to burn tokens at any time.
  • As the contract is implemented with Solidity 0.8.x, it is protected from overflow/underflow attacks.
  • The contract complies with the ERC20 standard.

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of ControlThe team can pause rewards at any time.WARNING
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Deprecated OpcodesN/APASS
Ether ThiefN/APASS
ExceptionsN/APASS
External CallsN/APASS
Integer Over/UnderflowN/APASS
Logical IssuesN/APASS
Multiple SendsN/APASS
SuicideN/APASS
State Change External CallsN/APASS
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

CryptoBearWatchClub Contract

CBWC Graph

CBWC Chart

												
($) = payable function
 # = non-constant function

Int = Internal
Ext = External
Pub = Public

  + [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

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 + [Lib] Strings 
    - [Int] toString
    - [Int] toHexString
    - [Int] toHexString

 +  ERC165 (IERC165)
    - [Pub] supportsInterface

 +  ERC721 (Context, ERC165, IERC721, IERC721Metadata)
    - [Pub]  #
    - [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 #
    - [Int] _setApprovalForAll #
    - [Prv] _checkOnERC721Received #
    - [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 #

 +  Ownable (Context)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Lib] Counters 
    - [Int] current
    - [Int] increment #
    - [Int] decrement #
    - [Int] reset #

 + [Lib] MerkleProof 
    - [Int] verify
    - [Int] processProof

 + [Int] IArkouda 
    - [Ext] updateReward #

 +  CryptoBearWatchClub (ERC721Enumerable, Ownable)
    - [Pub]  #
       - modifiers: ERC721
    - [Ext] flipSaleState #
       - modifiers: onlyOwner
    - [Ext] flipPresaleState #
       - modifiers: onlyOwner
    - [Ext] withdrawAll #
       - modifiers: onlyOwner
    - [Ext] setArkouda #
       - modifiers: onlyOwner
    - [Ext] setMerkleRootAndMintCount #
       - modifiers: onlyOwner
    - [Ext] startPresaleAuction #
       - modifiers: onlyOwner
    - [Ext] startAuction #
       - modifiers: onlyOwner
    - [Pub] setBaseURI #
       - modifiers: onlyOwner
    - [Ext] walletOfOwner
    - [Pub] dutchAuctionForPresale
    - [Pub] dutchAuctionForPublicMint
    - [Int] _baseURI
    - [Ext] presaleMint ($)
    - [Ext] mint ($)
    - [Prv] _mint #
    - [Prv] sendValue #
    - [Pub] transferFrom #
    - [Pub] safeTransferFrom #
    - [Pub] safeTransferFrom #

Arkouda Contract

ARK Token Graph

ARK Chart

												
($) = payable function
 # = non-constant function

Int = Internal
Ext = External
Pub = Public

   + [Int] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [Int] IERC20Metadata (IERC20)
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals

 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 +  ERC20 (Context, IERC20, IERC20Metadata)
    - [Pub]  #
    - [Pub] name
    - [Pub] symbol
    - [Pub] decimals
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] allowance
    - [Pub] approve #
    - [Pub] transferFrom #
    - [Pub] increaseAllowance #
    - [Pub] decreaseAllowance #
    - [Int] _transfer #
    - [Int] _mint #
    - [Int] _burn #
    - [Int] _approve #
    - [Int] _beforeTokenTransfer #
    - [Int] _afterTokenTransfer #

 +  Ownable (Context)
    - [Pub]  #
    - [Pub] owner
    - [Pub] renounceOwnership #
       - modifiers: onlyOwner
    - [Pub] transferOwnership #
       - modifiers: onlyOwner
    - [Int] _transferOwnership #

 + [Int] ICryptoBearWatchClub 
    - [Ext] walletOfOwner

 +  Arkouda (ERC20, Ownable)
    - [Pub]  #
       - modifiers: ERC20
    - [Ext] flipReward #
       - modifiers: onlyOwner
    - [Ext] startRewardGeneration #
       - modifiers: onlyOwner
    - [Ext] setTokenIdReward #
       - modifiers: onlyOwner
    - [Ext] setAllowedAddresses #
       - modifiers: onlyOwner
    - [Ext] updateReward #
    - [Ext] claimReward #
    - [Ext] getTotalClaimable
    - [Prv] getPendingReward
    - [Ext] burn #