Crypto Date - Smart Contract Audit Report

Summary

CryptoDate Audit Report CryptoDate is a new protocol that allows users to purchase CryptoDate NFTs as well as stake their CryptoDate tokens to earn rewards.

We reviewed the project team's Token, NFT, and Staking Rewards contracts at commit a3473951fb965ff98fc94504b2a744b4a2a395c9 on the team's Github repository.

Notes on the individual contracts

CryptoDate Token contract:
  • The total supply of the token will be set at the time of deployment and minted to the owner.
  • No minting functions are accessible beyond deployment.
  • Any user can burn their own tokens to reduce the total supply.
  • As the token has not yet been deployed to the mainnet, there was no token allocation for our team to analyze.
  • As the project is implemented with Solidity v0.8.0, it is protected from overflows.
  • The contract complies with the ERC20 token standard.

CryptoDate NFT Contract:
  • Each CryptoDate NFT represents a specific day between January 1st, 1950 and December 31st, 2049. Any user has the ability to purchase a CryptoDate NFT with ETH by entering in the desired date for the NFT that they would like to purchase. Once a date is claimed, it can no longer be claimed by another user.
  • At the time of writing this report, the standard price for purchasing 1 NFT is 0.1 ETH, however the owner can modify this price to any value at any time.
  • There are certain dates that are considered rare which is reflected in the price. The price for purchasing a CryptoDate NFT where the month and day are matching will cost the user 10 times the amount of the standard price.
  • The price for purchasing an NFT on any leap day will cost 100 times the amount of the standard price.
  • One half of the ETH collected from purchases is converted to WETH and is paired with CryptoDate tokens. This pair is then used the fund the Uniswap liquidity pool.
  • The other half of ETH collected from purchases is sent directly to the team's Treasury address.
  • Users who purchase NFTs also receive a reward in Cryptodate tokens. The amount of tokens rewarded to the user is 100 times the ETH value used to purchase their NFT.
  • Users can manually claim rewards in CryptoDate tokens based on the amount of CryptoDate NFTs in their balance.
  • Users will not recieve any awards if the contract balance does not have the sufficient amount of CryptoDate tokens.
  • Any user has the ability to recover ETH and tokens (with the exception of CryptoDate tokens) erroneously sent to the contract.
  • The contract complies with the ERC721 standard.
Staking Rewards Contract:
  • Users can stake their CryptoDate tokens into the Staking Rewards contract in order to earn more CryptoDate tokens as a reward.
  • There is a no fee associated with making a deposit to or withdrawing from the contract.
  • User's have the ability to claim their CryptoDate token rewards at any time.
  • Users will not recieve any rewards if the contract balance does not have the sufficient amount of CryptoDate tokens.
  • Users have the ability to begin a new period of staking if there is a sufficient enough balance of CryptoDate tokens to begin a new period.
  • The contract utilizes the SafeMath library to prevent overflows.
Audit Findings Summary
  • No external threats were identified.
  • Please ensure trust in the team as they have notable control in the ecosystem.
  • Date: October 1st, 2021

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
Integer Over/UnderflowN/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

Details: CryptoDateToken Contract


ERC20 Token Graph

Multi-file Token


 ($) = 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 #

 +  ERC20Burnable (Context, ERC20)
    - [Pub] burn #
    - [Pub] burnFrom #

 +  ERC20PresetFixedSupply (ERC20Burnable)
    - [Pub]  #
       - modifiers: ERC20

 +  CryptoDateToken (ERC20PresetFixedSupply)
    - [Pub]  #
       - modifiers: ERC20PresetFixedSupply
  
							

Details: CryptoDate NFT Contract


ERC20 Token Graph

Multi-file Token


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public

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

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

 + [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] Math 
    - [Int] max
    - [Int] min
    - [Int] average
    - [Int] ceilDiv

 +  ReentrancyGuard 
    - [Pub]  #

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

 + [Lib] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

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

 + [Int] IUniswapV2Router02 
    - [Ext] quote

 + [Int] IUniswapV2Pair 
    - [Ext] getReserves
    - [Ext] sync #

 + [Int] IWETH 
    - [Ext] deposit ($)

 + [Int] IExist 
    - [Ext] exists #

 +  CryptoDate (ERC721Enumerable, ReentrancyGuard, Ownable)
    - [Pub]  #
       - modifiers: ERC721
    - [Int] _baseURI
    - [Ext] mintWithETH ($)
       - modifiers: nonReentrant
    - [Ext] updatePrice #
       - modifiers: onlyOwner
    - [Pub] getPriceInETH
    - [Ext] migrationMint #
       - modifiers: nonReentrant
    - [Prv] valiDate #
    - [Ext] extendRewards #
    - [Pub] lastTimeRewardApplicable
    - [Pub] rewardPerToken
    - [Pub] earned
    - [Ext] getRewardForDuration
    - [Ext] getReward #
       - modifiers: nonReentrant
    - [Int] updateReward #
    - [Int] _beforeTokenTransfer #
    - [Ext] recoverWrongTokens #
    - [Ext] withdrawETH ($)
    - [Ext]  ($)
  
							

Details: Staking Rewards Contract


ERC20 Token Graph

Multi-file Token


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public

 + [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] Math 
    - [Int] max
    - [Int] min
    - [Int] average
    - [Int] ceilDiv

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

 +  ReentrancyGuard 
    - [Pub]  #

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

 + [Lib] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 +  StakingRewards (ReentrancyGuard)
    - [Pub]  #
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Pub] lastTimeRewardApplicable
    - [Pub] rewardPerToken
    - [Pub] earned
    - [Ext] getRewardForDuration
    - [Ext] stake #
       - modifiers: nonReentrant
    - [Ext] withdraw #
       - modifiers: nonReentrant
    - [Ext] getReward #
       - modifiers: nonReentrant
    - [Ext] startRewards #
    - [Int] updateReward #