BlackLemon Marketplace - Audit Report

Audit Summary

WEMP BSC Token and Bridges Audit Report BlackLemon is building a new marketplace that allows users to buy and sell NFTs.

For this audit, we reviewed the project team's contracts at commit 57476598c415e8ef6f4dbbf4add02c238c92fac2 on the team's private GitHub repository.

We previously reviewed the project team's token contract here and staking contract here.

Please ensure trust in the team prior to exchanging NFTs as they have substantial control in the ecosystem.

Date: January 3rd, 2022.

Audit Findings

Optimization - Finding #1

Description: Several functions are declared public, but are never called internally. A state variable can never be modified, but is not declared constant.
			
Functions:
- Exchange: setTreasury, setTreasuryPercent, atomicMatch

State Variables:
- ExchangeCore: personalSignPrefix

Recommendation: We recommend declaring these functions external and declaring the state variable constant for additional gas savings on each call.

Contracts Overview

Exchange and ExchangeCore Contracts:
  • These contracts serve as a marketplace which allows users to exchange tokens for NFTs.
  • Users can create a buy or sell order by submitting gasless signed messages and once a corresponding order is submitted and validated, the exchange transaction occurs.
  • Signed messages are stored on the team server and this process relies on off chain logic.
  • Users should excerise caution and ensure that any buy or sell order uses trusted tokens.
  • For users' orders to match, the following criteria must be met:
    • The type and amount of the specified exchange token must be equal.
    • Both orders must still be active.
    • Both users' signatures must be validated with the original hash.
    • Finally the seller and buyer addresses must be different.
  • For an order to be active, its expiration time must not have elapsed and the order must not have already been filled.
  • Upon order execution, a treasury tax is deducted from the sale amount and transferred to the treasury address.
  • The owner can update the treasury address and set the treasury tax percentage to any value at any time.
  • The contract utilizes ReentrancyGuard to prevent reentrancy attacks in applicable functions.
  • The contracts are deployed with Solidity v0.8.X, preventing any overflow/underflow-related issues.

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of ControlThe owner can set the treasury tax to any amount at any time.
Generating a signed message hash requires 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 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

Exchange Contract

Exchange Contract Graph

Exchange Contract Chart

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

Int = Internal
Ext = External
Pub = Public

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

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

 +  ReentrancyGuarded 

 +  EIP712 
    - [Int] hash

 +  ERC1271 
    - [Pub] isValidSignature

 + [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] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [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] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 +  ExchangeCore (ReentrancyGuarded, EIP712, Ownable)
    - [Int] setTreasury_ #
       - modifiers: onlyOwner
    - [Int] setTreasuryPercent_ #
       - modifiers: onlyOwner
    - [Prv] calculateShareAmount_
    - [Int] hashOrder_
    - [Int] hashToSign_
    - [Int] validateOrderParameters_
    - [Int] validateOrderAuthorization_
    - [Int] atomicMatch_ #
       - modifiers: reentrancyGuard

 +  Exchange (ExchangeCore)
    - [Ext] hashOrder
    - [Ext] hashToSign
    - [Pub] setTreasury #
       - modifiers: onlyOwner
    - [Pub] setTreasuryPercent #
       - modifiers: onlyOwner
    - [Ext] validateOrderParameters
    - [Ext] validateOrderAuthorization
    - [Pub] atomicMatch ($)

ExchangeCore Contract

ExchangeCore Contract Graph

ExchangeCore Contract Chart

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

Int = Internal
Ext = External
Pub = Public

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

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

 +  ReentrancyGuarded 

 +  EIP712 
    - [Int] hash

 +  ERC1271 
    - [Pub] isValidSignature

 + [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] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [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] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 +  ExchangeCore (ReentrancyGuarded, EIP712, Ownable)
    - [Int] setTreasury_ #
       - modifiers: onlyOwner
    - [Int] setTreasuryPercent_ #
       - modifiers: onlyOwner
    - [Prv] calculateShareAmount_
    - [Int] hashOrder_
    - [Int] hashToSign_
    - [Int] validateOrderParameters_
    - [Int] validateOrderAuthorization_
    - [Int] atomicMatch_ #
       - modifiers: reentrancyGuard