Wattbit

Smart Contract Audit Report

Audit Summary

Wattbit Audit Report Wattbit, Inc. is building a platform in which users can purchase TWL NFTs, receive Badges for holding TWL NFTs, and use Badges to earn commission on Sponsor NFT sales.

For this audit, we reviewed the following contracts on the Rinkeby Testnet:

Audit Findings

Please ensure trust in the team prior to investing as they have some control in the ecosystem.
Date: February 8th, 2022.
Updated: February 21st, 2022 to include resolutions to various findings.

Finding #1 - CBB - Medium (Resolved)

Description: The mintPresale() function is vulnerable to reentrancy attacks although it is limited to only whitelisted users. Reentrancy is made possible via the call to _safeMint(), which requires that the receiver has implemented the onERC721Received() function in the event that the receiver is a contract.
Risk/Impact: Whitelisted users can use the onERC721Received() function to execute arbitrary logic and reenter the mintPresale() function in an effort to mint NFTs at the presale price in excess of the individual presale limit and even the maximum supply limit.
Recommendation: The logic in the mintPresale() function should be restructured to follow the Checks-Effects-Interactions pattern. The presaleMints[msg.sender] value should be increased by the appropriate amount prior to minting any NFTs.
Resolution: The team has implemented the above recommendation.

Finding #2 - CBB & Sponsor - Low (Resolved)

Description: The reserve() function is vulnerable to reentrancy attacks although it is limited to situations in which the owner is a contract address.
Risk/Impact: The owner can use this function to perform a reentrancy attack in an effort to mint NFTs in excess of the maximum reserved amount.
Recommendation: The logic in the reserve() function should be restructured to follow the Checks-Effects-Interactions pattern. The reserved value should be increased by the appropriate amount prior to minting any NFTs.
Resolution: The team has implemented the above recommendation.

Finding #3 - CBB & Sponsor - Low

Description: Any excess ETH supplied to the contract during minting is not returned to the user.
Risk/Impact: Users will lose any excess funds sent as payment.
Recommendation: The contract should require the user supplies the exact amount of ETH needed to mint the desired amount of NFTs.

Finding #4 - Badge - Low (Resolved)

Description: The mint() function declaration uses the 'payable' keyword although no ETH payments are required.
Risk/Impact: Any ETH accidentally sent to the contract via this function will be locked in the contract forever. The risk of user confusion resulting in loss of ETH outweighs the small gas savings reaped by including the payable keyword.
Recommendation: Remove the 'payable' keyword from the function declaration.
Resolution: The team has implemented the above recommendation.

Finding #5 - Wattbit - Informational (Resolved)

Description: Several functions are declared public, but are never called internally.
Badge.uri, CBB.withdraw, Sponsor.mint, Sponsor.withdraw
Recommendation: These functions should be declared external for additional gas savings on each call.
Resolution: The team has implemented the above recommendation.

Finding #6 - Badge - Informational (Resolved)

Description: The sponsorNFT state variable can never be modified, but is not declared constant.
Recommendation: This state variable can be declared constant for additional gas savings on each call.
Resolution: The team has removed this state variable entirely; the rest of the code is unaffected by this change.

Contracts Overview

  • As the contracts are deployed with Solidity v0.8.10, they are protected from any underflow/overflow issues.
  • The team worked with us to ensure that the logic is well-structured to avoid reentrancy issues in applicable functions.
  • The contracts comply with the relevant ERC-1155 and ERC-721 token standards.
Badge Contract:
  • This contract is used to issue Badge NFTs to users representing ranks.
  • Anyone can mint themselves one Badge only one time; the Badge type the user will receive is based on their balance of TWL NFTs.
  • There are 5 types of Badges users may qualify for. The breakdown is as follows:
    • 1 TWL NFT yields Badge type 1.
    • 2 TWL NFTs yields Badge type 2.
    • 3 TWL NFTs yields Badge type 3.
    • 4 TWL NFTs yields Badge type 4.
    • 5 and up TWL NFTs yields Badge type 5.
  • This contract contains a single burn() function that is only accessible via the CBB contract; the purpose of this function is to burn the user's existing Badge NFT and mint the user a new Badge NFT based on their balance of TWL NFTs.
  • Badges cannot be transferred to any other address at any time.
  • The owner can set the TWL NFT contract address to any address at any time.
  • The owner can set the base URI value at any time.
  • This contract complies with the ERC-1155 multi token standard.
CBB Contract:
  • This contract is used to facilitate a presale and a public sale for TBI War Lords NFTs.
  • The maximum supply of TWL NFTs is 10,000.
  • While the presale is active, whitelisted users can each mint a maximum of 10 NFTs until the maximum supply has been reached; the user must provide a signature that can be used to recover the platform's signature verifier address to ensure that the user is indeed whitelisted.
  • The owner should exercise caution when granting users access to the presale and ensure that no more than 1,000 users are eligible as there is no total supply check within the mintPresale() function. As such, it is possible that the maximum supply limit may be exceeded.
  • Each NFT costs 0.05 ETH to mint during the presale.
  • While the public sale is active, users can mint up to 20 NFTs per transaction until the maximum supply has been reached.
  • Each NFT initially costs 0.095 ETH to mint during the public sale, but this cost can be changed by the project team at any time.
  • Users should exercise caution and ensure that the correct amount of ETH is supplied, as the contract will not return any excess ETH to the user.
  • The owner can mint up to 20 NFTs per transaction until either the maximum reserve supply of 1,000 NFTs has been reached, or the maximum total supply has been reached.
  • In the event that the address receiving a TWL NFT is a contract, the contract must have implemented the onERC721Received() function in order to successfully receive the NFT.
  • Upon receiving a TWL NFT, the contract calls the burn() function on the Badge contract in order to ensure the user has the correct Badge type at all times.
  • The owner can toggle the presale and the public sale at any time.
  • The owner can set the price of the TWL NFT during the public sale to any value at any time.
  • The owner can set the base URI value after deployment, but can disable this functionality at any time; once this functionality is disabled, it cannot be enabled again.
  • The owner can set the unrevealed URI to any value at any time; this value is used as a temporary URI before the true base URI has been revealed.
  • The owner can set the Badge contract address to any address at any time; users will not be able to transfer their TWL NFTs to any other address unless the Badge contract address is set.
  • The owner can set the signature verifier address to any address at any time.
  • The owner can withdraw all the ETH from the contract at any time.
  • This contract complies with the ERC-721 standard.
Sponsor Contract:
  • This contract is used to facilitate the sale of Sponsor NFTs.
  • The maximum supply of Sponsor NFTs is 10,000.
  • Only users who do not own a Badge NFT are able to mint Sponsor NFTs; however, users can mint a Badge NFT after minting themselves Sponsor NFTs.
  • Eligible users can mint up to 20 NFTs per transaction until the maximum supply has been reached.
  • Each NFT initially costs 0.085 ETH, but this cost can be changed by the project team at any time.
  • Users should exercise caution and ensure that the correct amount of ETH is supplied, as the contract will not return any excess ETH to the user.
  • The user can supply an "agent address" during minting, which may be eligible to receive a portion of the amount paid as commission based on their Badge type. The commission schedule is as follows:
    • Badge type 1 yields 10% commission.
    • Badge type 2 yields 20% commission.
    • Badge type 2 yields 30% commission.
    • Badge type 2 yields 40% commission.
    • Badge type 5 yields 50% commission.
  • The owner can mint up to 20 NFTs per transaction until either the maximum reserve supply of 100 NFTs has been reached, or the maximum total supply has been reached.
  • In the event that the address receiving a Sponsor NFT is a contract, the contract must have implemented the onERC721Received() function in order to successfully receive the NFT.
  • The owner can set the price of the Sponsor NFT during to any value at any time.
  • The owner can set the base URI value after deployment, but can disable this functionality at any time; once this functionality is disabled, it cannot be enabled again.
  • The owner can withdraw all the ETH from the contract at any time.
  • This contract complies with the ERC-721 standard.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Jump/Storage WriteN/APASS
Centralization of ControlThe owner can set the price of the TWL and Sponsor NFTs at any time.PASS
Compiler IssuesN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Ether/Token TheftN/APASS
Flash LoansN/APASS
Front RunningN/APASS
Improper EventsN/APASS
Improper Authorization SchemeN/APASS
Integer Over/UnderflowN/APASS
Logical IssuesN/APASS
Oracle IssuesN/APASS
Outdated Compiler VersionN/APASS
Race ConditionsN/APASS
ReentrancyN/APASS
Signature IssuesN/APASS
Unbounded LoopsN/APASS
Unused CodeN/APASS
Overall Contract Safety PASS

Badge Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = 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 #
    - [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] ECDSA 
    - [Prv] _throwError
    - [Int] tryRecover
    - [Int] recover
    - [Int] tryRecover
    - [Int] recover
    - [Int] tryRecover
    - [Int] recover
    - [Int] toEthSignedMessageHash
    - [Int] toEthSignedMessageHash
    - [Int] toTypedDataHash

 + [Int] IERC1155 (IERC165)
    - [Ext] balanceOf
    - [Ext] balanceOfBatch
    - [Ext] setApprovalForAll #
    - [Ext] isApprovedForAll
    - [Ext] safeTransferFrom #
    - [Ext] safeBatchTransferFrom #

 + [Int] IERC1155Receiver (IERC165)
    - [Ext] onERC1155Received #
    - [Ext] onERC1155BatchReceived #

 + [Int] IERC1155MetadataURI (IERC1155)
    - [Ext] uri

 +  ERC1155 (Context, ERC165, IERC1155, IERC1155MetadataURI)
    - [Pub]  #
    - [Pub] supportsInterface
    - [Pub] uri
    - [Pub] balanceOf
    - [Pub] balanceOfBatch
    - [Pub] setApprovalForAll #
    - [Pub] isApprovedForAll
    - [Pub] safeTransferFrom #
    - [Pub] safeBatchTransferFrom #
    - [Int] _safeTransferFrom #
    - [Int] _safeBatchTransferFrom #
    - [Int] _setURI #
    - [Int] _mint #
    - [Int] _mintBatch #
    - [Int] _burn #
    - [Int] _burnBatch #
    - [Int] _setApprovalForAll #
    - [Int] _beforeTokenTransfer #
    - [Prv] _doSafeTransferAcceptanceCheck #
    - [Prv] _doSafeBatchTransferAcceptanceCheck #
    - [Prv] _asSingletonArray

 +  CBB (ERC721, Ownable)
    - [Pub]  #
       - modifiers: ERC721
    - [Ext] mint ($)
    - [Ext] mintPresale ($)
    - [Ext] reserve #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Ext] setCBB_PRICE #
       - modifiers: onlyOwner
    - [Ext] togglePreSale #
       - modifiers: onlyOwner
    - [Ext] togglePublicSale #
       - modifiers: onlyOwner
    - [Ext] freezeURI #
       - modifiers: onlyOwner
    - [Ext] setSignatureVerifier #
       - modifiers: onlyOwner
    - [Ext] setBadgeContract #
       - modifiers: onlyOwner
    - [Pub] withdraw #
       - modifiers: onlyOwner
    - [Int] _baseURI
    - [Int] hashMessage
    - [Int] _beforeTokenTransfer #
    - [Prv] burnAndMintBadge #

 +  Badge (ERC1155, Ownable)
    - [Pub]  #
       - modifiers: ERC1155
    - [Ext] mint ($)
    - [Ext] burn #
    - [Pub] uri
    - [Ext] setcbbNFT #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Prv] burnAndMintByCBB #
    - [Prv] getBadgeType
    - [Int] _beforeTokenTransfer

CBB Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


 ($) = 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 #
    - [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] ECDSA 
    - [Prv] _throwError
    - [Int] tryRecover
    - [Int] recover
    - [Int] tryRecover
    - [Int] recover
    - [Int] tryRecover
    - [Int] recover
    - [Int] toEthSignedMessageHash
    - [Int] toEthSignedMessageHash
    - [Int] toTypedDataHash

 + [Int] IERC1155 (IERC165)
    - [Ext] balanceOf
    - [Ext] balanceOfBatch
    - [Ext] setApprovalForAll #
    - [Ext] isApprovedForAll
    - [Ext] safeTransferFrom #
    - [Ext] safeBatchTransferFrom #

 + [Int] IERC1155Receiver (IERC165)
    - [Ext] onERC1155Received #
    - [Ext] onERC1155BatchReceived #

 + [Int] IERC1155MetadataURI (IERC1155)
    - [Ext] uri

 +  ERC1155 (Context, ERC165, IERC1155, IERC1155MetadataURI)
    - [Pub]  #
    - [Pub] supportsInterface
    - [Pub] uri
    - [Pub] balanceOf
    - [Pub] balanceOfBatch
    - [Pub] setApprovalForAll #
    - [Pub] isApprovedForAll
    - [Pub] safeTransferFrom #
    - [Pub] safeBatchTransferFrom #
    - [Int] _safeTransferFrom #
    - [Int] _safeBatchTransferFrom #
    - [Int] _setURI #
    - [Int] _mint #
    - [Int] _mintBatch #
    - [Int] _burn #
    - [Int] _burnBatch #
    - [Int] _setApprovalForAll #
    - [Int] _beforeTokenTransfer #
    - [Prv] _doSafeTransferAcceptanceCheck #
    - [Prv] _doSafeBatchTransferAcceptanceCheck #
    - [Prv] _asSingletonArray

 +  Badge (ERC1155, Ownable)
    - [Pub]  #
       - modifiers: ERC1155
    - [Ext] mint ($)
    - [Ext] burn #
    - [Pub] uri
    - [Ext] setcbbNFT #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Prv] burnAndMintByCBB #
    - [Prv] getBadgeType
    - [Int] _beforeTokenTransfer

 +  CBB (ERC721, Ownable)
    - [Pub]  #
       - modifiers: ERC721
    - [Ext] mint ($)
    - [Ext] mintPresale ($)
    - [Ext] reserve #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Ext] setCBB_PRICE #
       - modifiers: onlyOwner
    - [Ext] togglePreSale #
       - modifiers: onlyOwner
    - [Ext] togglePublicSale #
       - modifiers: onlyOwner
    - [Ext] freezeURI #
       - modifiers: onlyOwner
    - [Ext] setSignatureVerifier #
       - modifiers: onlyOwner
    - [Ext] setBadgeContract #
       - modifiers: onlyOwner
    - [Pub] withdraw #
       - modifiers: onlyOwner
    - [Int] _baseURI
    - [Int] hashMessage
    - [Int] _beforeTokenTransfer #
    - [Prv] burnAndMintBadge #

Sponsor Contract

Smart Contract Audit - Inheritance

Smart Contract Audit - Graph


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

 +  ReentrancyGuard 
    - [Pub]  #

 + [Lib] ECDSA 
    - [Prv] _throwError
    - [Int] tryRecover
    - [Int] recover
    - [Int] tryRecover
    - [Int] recover
    - [Int] tryRecover
    - [Int] recover
    - [Int] toEthSignedMessageHash
    - [Int] toEthSignedMessageHash
    - [Int] toTypedDataHash

 + [Int] IERC1155 (IERC165)
    - [Ext] balanceOf
    - [Ext] balanceOfBatch
    - [Ext] setApprovalForAll #
    - [Ext] isApprovedForAll
    - [Ext] safeTransferFrom #
    - [Ext] safeBatchTransferFrom #

 + [Int] IERC1155Receiver (IERC165)
    - [Ext] onERC1155Received #
    - [Ext] onERC1155BatchReceived #

 + [Int] IERC1155MetadataURI (IERC1155)
    - [Ext] uri

 +  ERC1155 (Context, ERC165, IERC1155, IERC1155MetadataURI)
    - [Pub]  #
    - [Pub] supportsInterface
    - [Pub] uri
    - [Pub] balanceOf
    - [Pub] balanceOfBatch
    - [Pub] setApprovalForAll #
    - [Pub] isApprovedForAll
    - [Pub] safeTransferFrom #
    - [Pub] safeBatchTransferFrom #
    - [Int] _safeTransferFrom #
    - [Int] _safeBatchTransferFrom #
    - [Int] _setURI #
    - [Int] _mint #
    - [Int] _mintBatch #
    - [Int] _burn #
    - [Int] _burnBatch #
    - [Int] _setApprovalForAll #
    - [Int] _beforeTokenTransfer #
    - [Prv] _doSafeTransferAcceptanceCheck #
    - [Prv] _doSafeBatchTransferAcceptanceCheck #
    - [Prv] _asSingletonArray

 +  CBB (ERC721, Ownable)
    - [Pub]  #
       - modifiers: ERC721
    - [Ext] mint ($)
    - [Ext] mintPresale ($)
    - [Ext] reserve #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Ext] setCBB_PRICE #
       - modifiers: onlyOwner
    - [Ext] togglePreSale #
       - modifiers: onlyOwner
    - [Ext] togglePublicSale #
       - modifiers: onlyOwner
    - [Ext] freezeURI #
       - modifiers: onlyOwner
    - [Ext] setSignatureVerifier #
       - modifiers: onlyOwner
    - [Ext] setBadgeContract #
       - modifiers: onlyOwner
    - [Pub] withdraw #
       - modifiers: onlyOwner
    - [Int] _baseURI
    - [Int] hashMessage
    - [Int] _beforeTokenTransfer #
    - [Prv] burnAndMintBadge #

 +  Badge (ERC1155, Ownable)
    - [Pub]  #
       - modifiers: ERC1155
    - [Ext] mint ($)
    - [Ext] burn #
    - [Pub] uri
    - [Ext] setcbbNFT #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Prv] burnAndMintByCBB #
    - [Prv] getBadgeType
    - [Int] _beforeTokenTransfer

 +  Sponsor (ERC721, Ownable, ReentrancyGuard)
    - [Pub]  #
       - modifiers: ERC721
    - [Pub] mint ($)
       - modifiers: nonReentrant
    - [Ext] reserve #
       - modifiers: onlyOwner
    - [Ext] setPrice #
       - modifiers: onlyOwner
    - [Ext] setBaseURI #
       - modifiers: onlyOwner
    - [Ext] freezeURI #
       - modifiers: onlyOwner
    - [Pub] withdraw #
       - modifiers: onlyOwner
    - [Int] _baseURI
    - [Prv] calculateAgentCommission #