BitHotel Market - Smart Contract Audit Report

Audit Summary

Poseidon Audit Report BitHotel is releasing a new NFT marketplace where users are able to buy and sell BitHotel NFTs.

For this audit, we reviewed the following contracts on the Binance Smart Chain Testnet:

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: February 2nd, 2022.

Finding #1 - BithotelNFT - Informational

Description: The NFT creator is not set when an NFT is minted.
Risk/Impact: NFTs will not be burnable, and account migration will not succeed.
Recommendation: Set the NFT creator when minting NFTs.

Finding #2 - BithotelMarket - Informational

Description: The updateSale() and adminUpdateSale() functions access the wrong array when retrieving a sale.
Risk/Impact: Updates to sales will not affect the correct sale and will instead update an empty sale structure.
Recommendation: The sales should not be retrieved from the saleIdToBatchSale mapping and instead should be retreived from the saleIdToSale mapping.

Contracts Overview

  • The contracts are implemented using the Authorizable permission scheme.
  • This allows the contract owner to set various "roles" within the contract with each role having potentially different permissions.
  • The deployer is given the Default Admin role upon deployment.
  • The Default Admin may assign any role to any address at any time.
  • The contracts utilize SafeMath to prevent underflow/overflow.
  • The contracts utilize ReentrancyGuard where appropriate.
BithotelNFT Contract:
  • Any address with the Super Operator or Minter role may mint any number of NFTs at anytime; a sale is created for the minted NFTs in the Market contract.
  • An NFT's creator may burn any NFT they possess.
  • A Super Operator or Migrator may use a user's signed message to trigger a migration from an old address to a new address.
  • A migration will update the creator for all provided NFT IDs where the old address was the creator. Additionally, all provded NFT IDs that the old address owns will be transferred to the new address.
  • A Super Operator or Migrator role may use a user's signed message to update the payment address for all provided NFT IDs where the old address is the current payment address.
  • NFT metadata that contains information about the NFTs is stored using an off-chain URI endpoint.
  • Any address with the Super Operator or Whitelist role may add and remove addresses from the "permitted creators" whitelist. This whitelist has no function.
  • The Market Admin role may update the Market address and the base URI at any time.
BithotelMarket Contract:
  • Any user may use this contract to create a sale for an NFT.
  • The Super Operator or Minter role may create a batch sale, listing any number of NFTs by consecutive NFT IDs.
  • Users may buy an NFT for the specified number of tokens. If the seller is not the Treasury, a Foundation fee is taken and subsequently sent to the Treasury address.
  • The NFT contract and tokens used for purchasing NFTs are set upon deployment.
  • Users may update the price and cancel any of their sales at any time. The ability to update is non-functional due to logical issues.
  • A Super Operator or Migrator may use a user's signed message to update the seller on all of the provided sale IDs where the user is the seller.
  • The Default Admin role functions as the Market Admin.
  • The Market Admin may update the sale price and cancel any sale at any time. The ability to update is non-functional due to logical issues.
  • The Market Admin may update the market fees, coin address, and NFT contract address at any time.
BithotelTreasury Contract:
  • This contract is used to store proceeds from NFT sales and fees as well as manage various roles among the contracts.
  • The Default Admin role may withdraw all BNB and tokens in the contract at any time.
  • The Default Admin may add and remove permitted tokens at any time. Permitted tokens have no function.

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of Control
  • The team retains ownership functionality described above.
  • Fees may be set up to 100%.
  • The Market Admin may cancel and change the price of a sale at any time.
  • Signed messages require the use of off-chain logic.
  • 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 Issues
  • There is various non-functional logic.
  • WARNING
    Multiple SendsN/APASS
    SuicideN/APASS
    State Change External CallsN/APASS
    Unchecked RetvalN/APASS
    User Supplied AssertionN/APASS
    Critical Solidity CompilerN/APASS
    Overall Contract Safety WARNING

    BithotelNFT Contract

    smart_contract_audit_company

    token_audit

    
     ($) = payable function
     # = non-constant function
    
      + [Int] IERC1271 
        - [Ext] isValidSignature
    
     + [Lib] Strings 
        - [Int] toString
    
     + [Lib] ECDSA 
        - [Int] recover
        - [Int] recover
        - [Int] toEthSignedMessageHash
    
     + [Lib] BytesLibrary 
        - [Int] replaceAtIf
    
     + [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] AddressLibrary 
        - [Int] functionCallAndReturnAddress #
    
     + [Int] INFTMarket 
        - [Ext] adminUpdateConfig #
        - [Ext] getReserveAuction
        - [Ext] getReserveAuctionIdFor
        - [Ext] getReserveAuctionConfig
        - [Ext] createReserveAuction #
        - [Ext] updateReserveAuction #
        - [Ext] cancelReserveAuction #
        - [Ext] placeBid ($)
        - [Ext] finalizeReserveAuction #
        - [Ext] getMinBidAmount
        - [Ext] adminCancelReserveAuction #
        - [Ext] createSale #
        - [Ext] createBatchSale #
        - [Ext] adminAccountMigration #
        - [Ext] getFeeConfig
    
     +  NFTCore 
    
     + [Int] IOperatorRole 
        - [Ext] hasRole
        - [Ext] grantRole
        - [Ext] revokeRole
    
     + [Int] ITreasury 
        - [Ext] SUPER_OPERATOR_ROLE #
        - [Ext] ONLY_MINTER_ROLE #
        - [Ext] ONLY_MIGRATER_ROLE #
        - [Ext] ONLY_CANCEL_ROLE #
        - [Ext] ONLY_FEE_SETTER_ROLE #
        - [Ext] ONLY_WHITELIST_ROLE #
        - [Ext] withdrawFunds #
        - [Ext] grantAdmin #
        - [Ext] revokeAdmin #
        - [Ext] isAdmin
        - [Ext] grantSuperOperator #
        - [Ext] revokeSuperOperator #
        - [Ext] isSuperOperator
        - [Ext] isMigraterOperator
        - [Ext] isMinterOperator
        - [Ext] isCancelOperator
        - [Ext] isFeeSetterOperator
        - [Ext] isWhitelistOperator
        - [Ext] initialize #
    
     + [Int] IAdminRole 
        - [Ext] isAdmin
    
     + [Lib] StringsUpgradeable 
        - [Int] toString
    
     + [Lib] EnumerableMapUpgradeable 
        - [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] EnumerableSetUpgradeable 
        - [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] SafeMathUpgradeable 
        - [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] IERC721ReceiverUpgradeable 
        - [Ext] onERC721Received #
    
     + [Lib] AddressUpgradeable 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Prv] _verifyCallResult
    
     +  Initializable 
        - [Prv] _isConstructor
    
     +  TreasuryNode (Initializable)
        - [Int] _initializeTreasuryNode #
           - modifiers: initializer
        - [Pub] getTreasury
    
     +  MarketOperatorRole (TreasuryNode)
        - [Int] _isMigraterOperator
        - [Int] _isCancelOperator
        - [Int] _isFeeSetterOperator
        - [Int] _isMinterOperator
        - [Int] _isSuperOperator
        - [Int] _isWhitelistOperator
    
     +  AccountMigration (MarketOperatorRole)
        - [Int] _isValidSignatureNow
        - [Int] _toAsciiString
        - [Prv] _char
        - [Int] _toEthSignedMessage
    
     +  MarketAdminRole (TreasuryNode)
        - [Int] _isMarketAdmin
    
     +  ContextUpgradeable (Initializable)
        - [Int] __Context_init #
           - modifiers: initializer
        - [Int] __Context_init_unchained #
           - modifiers: initializer
        - [Int] _msgSender
        - [Int] _msgData
    
     + [Int] IERC165Upgradeable 
        - [Ext] supportsInterface
    
     + [Int] IERC721Upgradeable (IERC165Upgradeable)
        - [Ext] balanceOf
        - [Ext] ownerOf
        - [Ext] safeTransferFrom #
        - [Ext] transferFrom #
        - [Ext] approve #
        - [Ext] getApproved
        - [Ext] setApprovalForAll #
        - [Ext] isApprovedForAll
        - [Ext] safeTransferFrom #
    
     + [Int] IERC721EnumerableUpgradeable (IERC721Upgradeable)
        - [Ext] totalSupply
        - [Ext] tokenOfOwnerByIndex
        - [Ext] tokenByIndex
    
     + [Int] IERC721MetadataUpgradeable (IERC721Upgradeable)
        - [Ext] name
        - [Ext] symbol
        - [Ext] tokenURI
    
     +  ERC165Upgradeable (Initializable, IERC165Upgradeable)
        - [Int] __ERC165_init #
           - modifiers: initializer
        - [Int] __ERC165_init_unchained #
           - modifiers: initializer
        - [Pub] supportsInterface
        - [Int] _registerInterface #
    
     +  HasSecondarySaleFees (Initializable, ERC165Upgradeable)
        - [Int] _initializeHasSecondarySaleFees #
           - modifiers: initializer
        - [Pub] getFeeRecipients
        - [Pub] getFeeBps
    
     +  ERC721Upgradeable (Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable)
        - [Int] __ERC721_init #
           - modifiers: initializer
        - [Int] __ERC721_init_unchained #
           - modifiers: initializer
        - [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 #
    
     +  NFT721Creator (Initializable, AccountMigration, ERC721Upgradeable)
        - [Int] _initializeNFT721Creator #
           - modifiers: initializer
        - [Pub] registerInterfaces #
        - [Pub] tokenCreator
        - [Pub] getTokenCreatorPaymentAddress
        - [Int] _updateTokenCreator #
        - [Int] _setTokenCreatorPaymentAddress #
        - [Pub] burn #
           - modifiers: onlyCreatorAndOwner
        - [Pub] adminAccountMigration #
           - modifiers: onlyAuthorizedAccountMigration
        - [Pub] adminAccountMigrationForPaymentAddresses #
           - modifiers: onlyAuthorizedAccountMigration
        - [Prv] _adminAccountRecoveryForPaymentAddresses #
        - [Pub] isWhitelistedCreator
        - [Pub] grantMint #
           - modifiers: onlyWhitelistOperator
        - [Pub] revokeMint #
           - modifiers: onlyWhitelistOperator
        - [Int] _burn #
    
     +  NFT721Metadata (NFT721Creator)
        - [Pub] getTokenIPFSPath
        - [Pub] getHasCreatorMintedIPFSHash
        - [Int] _updateBaseURI #
        - [Int] _setTokenIPFSPath #
        - [Int] _burn #
    
     +  NFT721Market (TreasuryNode, HasSecondarySaleFees, NFT721Creator)
        - [Pub] getNFTMarket
        - [Int] _updateNFTMarket #
        - [Pub] getFeeRecipients
        - [Pub] getFeeBps
        - [Pub] getFees
    
     +  NFT721Mint (Initializable, AccountMigration, ERC721Upgradeable, NFT721Creator, NFT721Market, NFT721Metadata)
        - [Pub] getNextTokenId
        - [Int] _initializeNFT721Mint #
           - modifiers: initializer
        - [Pub] mint #
        - [Int] _mint #
        - [Pub] getTokenType
        - [Int] _burn #
    
     +  NFT721 (TreasuryNode, MarketAdminRole, MarketOperatorRole, AccountMigration, ERC165Upgradeable, HasSecondarySaleFees, ERC721Upgradeable, NFTCore, NFT721Creator, NFT721Market, NFT721Metadata, NFT721Mint)
        - [Pub] initialize #
           - modifiers: initializer
        - [Pub] adminUpdateConfig #
           - modifiers: onlyMarketAdmin
        - [Int] _burn #
    
     +  BithotelNFT (NFT721)
        - [Pub] getVersion
      
    
    							

    BithotelMarket Contract

    smart_contract_audit_company

    token_audit

    
     ($) = payable function
     # = non-constant function
    
     +  NFTCore 
    
     + [Int] INFTMarket 
        - [Ext] adminUpdateConfig #
        - [Ext] getReserveAuction
        - [Ext] getReserveAuctionIdFor
        - [Ext] getReserveAuctionConfig
        - [Ext] createReserveAuction #
        - [Ext] updateReserveAuction #
        - [Ext] cancelReserveAuction #
        - [Ext] placeBid ($)
        - [Ext] finalizeReserveAuction #
        - [Ext] getMinBidAmount
        - [Ext] adminCancelReserveAuction #
        - [Ext] createSale #
        - [Ext] createBatchSale #
        - [Ext] adminAccountMigration #
        - [Ext] getFeeConfig
    
     + [Lib] BytesLibrary 
        - [Int] replaceAtIf
    
     + [Lib] StringsUpgradeable 
        - [Int] toString
    
     + [Lib] EnumerableMapUpgradeable 
        - [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] EnumerableSetUpgradeable 
        - [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
    
     + [Int] IERC721ReceiverUpgradeable 
        - [Ext] onERC721Received #
    
     + [Int] IERC1271 
        - [Ext] isValidSignature
    
     + [Lib] Strings 
        - [Int] toString
    
     + [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] AddressLibrary 
        - [Int] functionCallAndReturnAddress #
    
     + [Lib] ECDSA 
        - [Int] recover
        - [Int] recover
        - [Int] toEthSignedMessageHash
    
     + [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] INFT721 (IERC721, IERC721Enumerable, IERC721Metadata)
        - [Ext] burn #
        - [Ext] getTreasury
        - [Ext] getNFTMarket
        - [Ext] adminAccountMigration #
        - [Ext] baseURI
        - [Ext] tokenCreator
        - [Ext] adminUpdateConfig #
        - [Ext] getTokenCreatorPaymentAddress
        - [Ext] getNextTokenId
        - [Ext] mint #
        - [Ext] mintAndApproveMarket #
        - [Ext] mintWithCreatorPaymentAddress #
        - [Ext] mintWithCreatorPaymentAddressAndApproveMarket #
        - [Ext] mintWithCreatorPaymentFactory #
        - [Ext] mintWithCreatorPaymentFactoryAndApproveMarket #
    
     +  Constants 
    
     + [Lib] SafeMathUpgradeable 
        - [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] IERC165Upgradeable 
        - [Ext] supportsInterface
    
     + [Int] IERC721Upgradeable (IERC165Upgradeable)
        - [Ext] balanceOf
        - [Ext] ownerOf
        - [Ext] safeTransferFrom #
        - [Ext] transferFrom #
        - [Ext] approve #
        - [Ext] getApproved
        - [Ext] setApprovalForAll #
        - [Ext] isApprovedForAll
        - [Ext] safeTransferFrom #
    
     + [Int] IERC721EnumerableUpgradeable (IERC721Upgradeable)
        - [Ext] totalSupply
        - [Ext] tokenOfOwnerByIndex
        - [Ext] tokenByIndex
    
     + [Int] IERC721MetadataUpgradeable (IERC721Upgradeable)
        - [Ext] name
        - [Ext] symbol
        - [Ext] tokenURI
    
     +  NFTMarketCore 
        - [Int] _getSellerFor
    
     + [Int] IOperatorRole 
        - [Ext] hasRole
        - [Ext] grantRole
        - [Ext] revokeRole
    
     + [Int] ITreasury 
        - [Ext] SUPER_OPERATOR_ROLE #
        - [Ext] ONLY_MINTER_ROLE #
        - [Ext] ONLY_MIGRATER_ROLE #
        - [Ext] ONLY_CANCEL_ROLE #
        - [Ext] ONLY_FEE_SETTER_ROLE #
        - [Ext] ONLY_WHITELIST_ROLE #
        - [Ext] withdrawFunds #
        - [Ext] grantAdmin #
        - [Ext] revokeAdmin #
        - [Ext] isAdmin
        - [Ext] grantSuperOperator #
        - [Ext] revokeSuperOperator #
        - [Ext] isSuperOperator
        - [Ext] isMigraterOperator
        - [Ext] isMinterOperator
        - [Ext] isCancelOperator
        - [Ext] isFeeSetterOperator
        - [Ext] isWhitelistOperator
        - [Ext] initialize #
    
     + [Int] IAdminRole 
        - [Ext] isAdmin
    
     + [Int] IERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Lib] AddressUpgradeable 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Prv] _verifyCallResult
    
     +  Initializable 
        - [Prv] _isConstructor
    
     +  ERC165Upgradeable (Initializable, IERC165Upgradeable)
        - [Int] __ERC165_init #
           - modifiers: initializer
        - [Int] __ERC165_init_unchained #
           - modifiers: initializer
        - [Pub] supportsInterface
        - [Int] _registerInterface #
    
     +  HasSecondarySaleFees (Initializable, ERC165Upgradeable)
        - [Int] _initializeHasSecondarySaleFees #
           - modifiers: initializer
        - [Pub] getFeeRecipients
        - [Pub] getFeeBps
    
     +  ContextUpgradeable (Initializable)
        - [Int] __Context_init #
           - modifiers: initializer
        - [Int] __Context_init_unchained #
           - modifiers: initializer
        - [Int] _msgSender
        - [Int] _msgData
    
     +  ERC721Upgradeable (Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721Upgradeable, IERC721MetadataUpgradeable, IERC721EnumerableUpgradeable)
        - [Int] __ERC721_init #
           - modifiers: initializer
        - [Int] __ERC721_init_unchained #
           - modifiers: initializer
        - [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 #
    
     +  TreasuryNode (Initializable)
        - [Int] _initializeTreasuryNode #
           - modifiers: initializer
        - [Pub] getTreasury
    
     +  NFTMarketFees (Constants, Initializable, TreasuryNode, NFTMarketCore)
        - [Pub] getFeeConfig
        - [Int] _distributeFunds #
        - [Int] _updateMarketFees #
        - [Pub] getNFTContract
    
     +  MarketOperatorRole (TreasuryNode)
        - [Int] _isMigraterOperator
        - [Int] _isCancelOperator
        - [Int] _isFeeSetterOperator
        - [Int] _isMinterOperator
        - [Int] _isSuperOperator
        - [Int] _isWhitelistOperator
    
     +  AccountMigration (MarketOperatorRole)
        - [Int] _isValidSignatureNow
        - [Int] _toAsciiString
        - [Prv] _char
        - [Int] _toEthSignedMessage
    
     +  MarketAdminRole (TreasuryNode)
        - [Int] _isMarketAdmin
    
     +  NFT721Creator (Initializable, AccountMigration, ERC721Upgradeable)
        - [Int] _initializeNFT721Creator #
           - modifiers: initializer
        - [Pub] registerInterfaces #
        - [Pub] tokenCreator
        - [Pub] getTokenCreatorPaymentAddress
        - [Int] _updateTokenCreator #
        - [Int] _setTokenCreatorPaymentAddress #
        - [Pub] burn #
           - modifiers: onlyCreatorAndOwner
        - [Pub] adminAccountMigration #
           - modifiers: onlyAuthorizedAccountMigration
        - [Pub] adminAccountMigrationForPaymentAddresses #
           - modifiers: onlyAuthorizedAccountMigration
        - [Prv] _adminAccountRecoveryForPaymentAddresses #
        - [Pub] isWhitelistedCreator
        - [Pub] grantMint #
           - modifiers: onlyWhitelistOperator
        - [Pub] revokeMint #
           - modifiers: onlyWhitelistOperator
        - [Int] _burn #
    
     +  NFT721Metadata (NFT721Creator)
        - [Pub] getTokenIPFSPath
        - [Pub] getHasCreatorMintedIPFSHash
        - [Int] _updateBaseURI #
        - [Int] _setTokenIPFSPath #
        - [Int] _burn #
    
     +  NFT721Market (TreasuryNode, HasSecondarySaleFees, NFT721Creator)
        - [Pub] getNFTMarket
        - [Int] _updateNFTMarket #
        - [Pub] getFeeRecipients
        - [Pub] getFeeBps
        - [Pub] getFees
    
     +  NFT721Mint (Initializable, AccountMigration, ERC721Upgradeable, NFT721Creator, NFT721Market, NFT721Metadata)
        - [Pub] getNextTokenId
        - [Int] _initializeNFT721Mint #
           - modifiers: initializer
        - [Pub] mint #
        - [Int] _mint #
        - [Pub] getTokenType
        - [Int] _burn #
    
     +  ReentrancyGuardUpgradeable (Initializable)
        - [Int] __ReentrancyGuard_init #
           - modifiers: initializer
        - [Int] __ReentrancyGuard_init_unchained #
           - modifiers: initializer
    
     +  NFTMarketSale (MarketAdminRole, AccountMigration, ReentrancyGuardUpgradeable, NFTMarketFees)
        - [Int] _initializeNFTMarketSale #
        - [Int] _getNextAndIncrementSaleId #
        - [Pub] getSale
        - [Pub] getSaleIdFor
        - [Pub] createSale #
           - modifiers: onlyValidSaleConfig,nonReentrant
        - [Pub] createBatchSale #
           - modifiers: onlyValidSaleConfig,nonReentrant
        - [Pub] updateSale #
           - modifiers: onlyValidSaleConfig
        - [Pub] adminUpdateSale #
           - modifiers: onlyValidSaleConfig,onlyMarketAdmin
        - [Pub] cancelSale #
           - modifiers: nonReentrant
        - [Pub] buyToken #
           - modifiers: nonReentrant
        - [Pub] adminCancelSale #
           - modifiers: onlyMarketAdmin
        - [Pub] adminAccountMigrationSale #
           - modifiers: onlyAuthorizedAccountMigration
    
     +  NFTMarket (TreasuryNode, MarketAdminRole, MarketOperatorRole, NFTMarketCore, NFTMarketSale)
        - [Pub] initialize #
           - modifiers: initializer
        - [Pub] adminUpdateConfig #
           - modifiers: onlyMarketAdmin
        - [Int] _getSellerFor
    
     +  BithotelMarket (NFTMarket)
    
      
    
    							

    BithotelTreasury Contract

    smart_contract_audit_company

    token_audit

    
     ($) = payable function
     # = non-constant function
    
     + [Int] ISendValueWithFallbackWithdraw 
        - [Ext] withdraw #
    
     + [Int] IERC20 
        - [Ext] totalSupply
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     + [Lib] EnumerableSetUpgradeable 
        - [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] AddressUpgradeable 
        - [Int] isContract
        - [Int] sendValue #
        - [Int] functionCall #
        - [Int] functionCall #
        - [Int] functionCallWithValue #
        - [Int] functionCallWithValue #
        - [Int] functionStaticCall
        - [Int] functionStaticCall
        - [Prv] _verifyCallResult
    
     +  Initializable 
        - [Prv] _isConstructor
    
     +  ContextUpgradeable (Initializable)
        - [Int] __Context_init #
           - modifiers: initializer
        - [Int] __Context_init_unchained #
           - modifiers: initializer
        - [Int] _msgSender
        - [Int] _msgData
    
     +  AccessControlUpgradeable (Initializable, ContextUpgradeable)
        - [Int] __AccessControl_init #
           - modifiers: initializer
        - [Int] __AccessControl_init_unchained #
           - modifiers: initializer
        - [Pub] hasRole
        - [Pub] getRoleMemberCount
        - [Pub] getRoleMember
        - [Pub] getRoleAdmin
        - [Pub] grantRole #
        - [Pub] revokeRole #
        - [Pub] renounceRole #
        - [Int] _setupRole #
        - [Int] _setRoleAdmin #
        - [Prv] _grantRole #
        - [Prv] _revokeRole #
    
     +  OperatorRole (Initializable, AccessControlUpgradeable)
        - [Pub] isSuperOperator
        - [Pub] grantSuperOperator #
        - [Pub] revokeSuperOperator #
        - [Pub] isMigraterOperator
        - [Pub] isMinterOperator
        - [Pub] isCancelOperator
        - [Pub] isFeeSetterOperator
        - [Pub] isWhitelistOperator
    
     +  AdminRole (Initializable, AccessControlUpgradeable)
        - [Int] _initializeAdminRole #
           - modifiers: initializer
        - [Pub] isAdmin
        - [Pub] grantAdmin #
        - [Pub] revokeAdmin #
    
     +  WithdrawFromEscrow (AdminRole)
        - [Ext] withdrawFromEscrow #
           - modifiers: onlyAdmin
    
     +  CollateralManagement (AdminRole)
        - [Ext]  ($)
        - [Pub] withdrawFunds #
           - modifiers: onlyAdmin
        - [Pub] withdrawTokens #
           - modifiers: onlyAdmin
        - [Pub] unregisterToken #
           - modifiers: onlyAdmin
        - [Pub] registerToken #
           - modifiers: onlyAdmin
        - [Pub] isTokenPermitted
    
     +  Treasury (AdminRole, OperatorRole, CollateralManagement, WithdrawFromEscrow)
        - [Pub] initialize #
           - modifiers: initializer
    
     +  BithotelTreasury (Treasury)