Quantic - Smart Contract Audit Report

Audit Summary

Quantic Audit Report Quantic ($Quantic) is a new BEP-20 token that features automatic liquidity adds and pays holders dividends in BSC-USD.

For this audit, we reviewed the Quantic and DividendDistributor contracts using code 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: February 10th, 2022.
Updated: February 14th, 2022 to reflect updates to the contract that resolve Findings #1 and #2.

Finding #1 - Quantic - Medium (Resolved)

Description: The owner can use either the multiTransfer() or multiTransfer_fixed() function to initiate token airdrops that are funded by any address that the owner specifies.
			
function multiTransfer(address from, address[] calldata addresses, uint256[] calldata tokens) external onlyOwner {
...
for(uint i=0; i < addresses.length; i++){
	_basicTransfer(from,addresses[i],tokens[i]);
	}
}
function multiTransfer_fixed(address from, address[] calldata addresses, uint256 tokens) external onlyOwner {
...
for(uint i=0; i < addresses.length; i++){
	_basicTransfer(from,addresses[i],tokens);
	}
}
Risk/Impact: The owner can use these two functions to transfer any user's tokens to another address without approval.
Recommendation: We recommend removing the from parameter and using msg.sender to fund the airdrop instead.
Resolution: The team has implemented the above recommendation.

Finding #2 - Quantic - Informational (Resolved)

Description: Several functions are declared public, but are never called internally.
			
rebase_percentage, tradingStatus, launchStatus, enable_blacklist, manage_blacklist, cooldownEnabled, isOverLiquified
Recommendation: We recommend declaring these functions external for additional gas savings on each call.
Resolution: The team has declared these variables external.

Contracts Overview

  • The total supply of the token is set to 4 billion $Quantic [4,000,000,000].
  • No mint or burn functions are present; though the circulating supply can be reduced by sending tokens to the 0x..dead address if desired.
  • There was no token allocation for our team to analyze as the contract has yet to be deployed to the mainnet.

  • The team can activate a rebase mechanism that will automatically adjust the token's circulating supply according to a rebase percentage determined by the team.
  • This mechanism will rebase the circulating supply to increase or decrease the price of an individual token while increasing or decreasing each holder's balance at the provided rate. When rebasing occurs, the total market cap for the token will not be directly affected as a result of this mechanism.
  • The rebase function properly calls sync() on the PancakeSwap Pair contract to prevent theft-of-liquidity attacks that have occurred with other rebase tokens.

  • The team must manually enable trading in order for trading to take place on the platform. Only accounts that have been authorized by the owner can trade when trading is set to disabled.
  • There is a tax fee on all transfers where neither the sender nor the recipient is excluded from fees.
  • If the transaction is a sell trade, the tax fee is multiplied by a sell tax multiplier value determined by the team.
  • The fees charged on transfers are stored in the contract and once the threshold number of tokens (determined by the owner) is met, a swap will occur for the purpose of funding Pancakeswap liquidity.
  • Liquidity-adds are funded by selling a portion of the tokens collected as fees (after the threshold value of tokens is met), then pairing the received BNB with the token, and adding it as liquidity to the BNB pair.
  • The LP tokens received through this process are sent to the Liquidity address set by the team. We recommend that the team lock these newly acquired LP tokens.
  • The tokens collected from the Treasury Fee are swapped for BNB and sent to the team's Treasury wallet.
  • The tokens collected from the Sustainability Fee are swapped for BNB and sent to the team's Sustainability wallet.
  • The tokens collected from the Reflection Fee are swapped for BNB and sent to the Distributor contract where they are swapped for BSC-USD and distributed as rewards.
  • The contract features a cooldown mechanism that prevents a user from buying tokens from Pancakeswap if the cooldown time (set by the team) since their last buy has not yet elapsed.
  • The contract features an antisniper mechanism that is triggered when a user attempts to buy tokens before the set number of blocks (set by the team) has passed since the launch time of the contract. The account initiating the transfer will be taxed at a 99% rate.
  • The contract utilizes the SafeMath library to protect against overflows/underflows along with following the BEP-20 standard.

  • Any user that holds any amount of $Quantic tokens is eligible to claim dividends once the amount of dividends they are due reaches a minimum threshold value determined by the team.
  • Once dividends are distributed, they will need to be claimed; claiming happens automatically on each transfer.
  • Dividend rewards can also be claimed manually by kicking off the claim cycle, which will process all eligible token holders.
  • There is a wait-time (set by the owner) between claiming dividend rewards.
  • Claimed dividends are sent to the user's wallet address.
Ownership Controls:
  • The owner can assign one address to a Master role and multiple addresses to an Authorized role at any time.
  • The Master address can initiate the rebase mechanism at any time, as long as the contract is not currently swapping.
  • The owner can enable/disable trading at any time.
  • The owner can update the sell multiplier when selling to Pancakeswap up to 20% at any time.
  • The owner can manually set the launch time of the contract to any value at any time. We recommend that this function is only used once by providing the correct block, to avoid setting all non-selling transfer fees to 99%.
  • The owner can enable/disable the use of a transfer blacklist, as well as add/remove addresses from it at any time. Addresses that are added to the blacklist will not be able to participate in transfers.
  • The owner can update the cooldown period to any value at any time.
  • The owner can set and update a maximum wallet amount that will prevent transfers from occurring if the recipient's token balance will exceed the value set by the team.
  • The owner can set and update a maximum transaction amount at any time, which will impose a limit to the number of tokens that can be transferred during any given transaction.
  • The owner can initiate $Quantic token airdrops to any users at any time.
  • The owner can withdraw any BEP-20 tokens from the contract address at any time.

  • Authorized addresses can set each fee percentage to any value as long as the total fee percentage combined does not exceed 20%.
  • Authorized addresses can update the team's Liquidity wallet, Treasury wallet, and Sustainability wallet to any addresses at any time.
  • Authorized addresses can exclude addresses from fees, the cooldown mechanism, and the maximum transaction amount at any time.
  • Authorized addresses can exclude any address from dividends at any time.
  • Authorized addresses can update the threshold number of tokens that triggers the token swapping functionality to any value at any time.
  • Authorized addresses can disable the automatic swapping functionality at any time.
  • Authorized addresses can update the maximum amount of gas used for processing to a value up to 900,000 at any time.
  • Authorized addresses can update the amount of time that must elapse between claiming dividends to any amount of time. Authorized addresses can also update the minimum rewards payout that a holder must have in order to be able to claim.
  • Authorized addresses can transfer any BNB from the contract address balance to their own address or the Treasury wallet at any time.

External Threat Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of Control
  • The LP tokens generated from automatic liquidity adds are sent to the team's Liquidity wallet.
  • The owner can blacklist any account from being able to participate in transfers.
  • The team can adjust the circulating supply via the rebase mechanism.
  • The owner can set total fee percentages up to 20%.
  • WARNING
    Delegate Call to Untrusted ContractN/APASS
    Dependence on Predictable VariablesN/APASS
    Deprecated OpcodesN/APASS
    Ether ThiefN/APASS
    ExceptionsN/APASS
    External CallsN/APASS
    Flash LoansN/APASS
    Integer Over/UnderflowN/APASS
    Logical IssuesN/APASS
    Multiple SendsN/APASS
    OraclesN/APASS
    SuicideN/APASS
    State Change External CallsN/APASS
    Unchecked RetvalN/APASS
    User Supplied AssertionN/APASS
    Critical Solidity CompilerN/APASS
    Overall Contract Safety PASS

    Function Graph

    BEP20 Token Graph

    Inheritance Chart

    Multi-file Token

    Functions Overview

    												
    ($) = payable function
     # = non-constant function
    
     + [Lib] SafeMath 
        - [Int] add
        - [Int] sub
        - [Int] sub
        - [Int] mul
        - [Int] div
        - [Int] div
    
     + [Lib] SafeMathInt 
        - [Int] mul
        - [Int] div
        - [Int] sub
        - [Int] add
        - [Int] abs
    
     + [Int] IBEP20 
        - [Ext] totalSupply
        - [Ext] decimals
        - [Ext] symbol
        - [Ext] name
        - [Ext] getOwner
        - [Ext] balanceOf
        - [Ext] transfer #
        - [Ext] allowance
        - [Ext] approve #
        - [Ext] transferFrom #
    
     +  Auth 
        - [Pub]  #
        - [Pub] authorize #
           - modifiers: onlyOwner
        - [Pub] unauthorize #
           - modifiers: onlyOwner
        - [Pub] isOwner
        - [Pub] isAuthorized
        - [Pub] transferOwnership #
           - modifiers: onlyOwner
    
     + [Int] IDEXFactory 
        - [Ext] createPair #
    
     + [Int] InterfaceLP 
        - [Ext] sync #
    
     + [Int] IDEXRouter 
        - [Ext] factory
        - [Ext] WETH
        - [Ext] addLiquidity #
        - [Ext] addLiquidityETH ($)
        - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
        - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
        - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #
    
     + [Int] IDividendDistributor 
        - [Ext] setDistributionCriteria #
        - [Ext] setShare #
        - [Ext] deposit ($)
        - [Ext] process #
    
     +  DividendDistributor (IDividendDistributor)
        - [Pub]  #
        - [Ext] setDistributionCriteria #
           - modifiers: onlyToken
        - [Ext] setShare #
           - modifiers: onlyToken
        - [Ext] deposit ($)
           - modifiers: onlyToken
        - [Ext] process #
           - modifiers: onlyToken
        - [Int] shouldDistribute
        - [Int] distributeDividend #
        - [Ext] claimDividend #
        - [Pub] getUnpaidEarnings
        - [Int] getCumulativeDividends
        - [Int] addShareholder #
        - [Int] removeShareholder #
    
     +  Quantic (IBEP20, Auth)
        - [Pub] rebase_percentage #
           - modifiers: onlyMaster
        - [Pub] rebase #
           - modifiers: onlyMaster
        - [Pub]  #
           - modifiers: Auth
        - [Ext]  ($)
        - [Ext] totalSupply
        - [Ext] decimals
        - [Ext] symbol
        - [Ext] name
        - [Ext] getOwner
        - [Pub] balanceOf
        - [Ext] allowance
        - [Pub] approve #
        - [Ext] approveMax #
        - [Ext] transfer #
        - [Ext] transferFrom #
        - [Int] _transferFrom #
        - [Int] _basicTransfer #
        - [Int] checkTxLimit
        - [Int] shouldTakeFee
        - [Int] takeFee #
        - [Int] shouldSwapBack
        - [Ext] clearStuckBalance #
           - modifiers: authorized
        - [Ext] clearStuckBalance_sender #
           - modifiers: authorized
        - [Ext] set_sell_multiplier #
           - modifiers: onlyOwner
        - [Pub] tradingStatus #
           - modifiers: onlyOwner
        - [Pub] launchStatus #
           - modifiers: onlyOwner
        - [Pub] enable_blacklist #
           - modifiers: onlyOwner
        - [Pub] manage_blacklist #
           - modifiers: onlyOwner
        - [Pub] cooldownEnabled #
           - modifiers: onlyOwner
        - [Int] swapBack #
           - modifiers: swapping
        - [Ext] setIsDividendExempt #
           - modifiers: authorized
        - [Ext] setIsFeeExempt #
           - modifiers: authorized
        - [Ext] setIsTxLimitExempt #
           - modifiers: authorized
        - [Ext] setIsTimelockExempt #
           - modifiers: authorized
        - [Ext] setFees #
           - modifiers: authorized
        - [Ext] setFeeReceivers #
           - modifiers: authorized
        - [Ext] setSwapBackSettings #
           - modifiers: authorized
        - [Ext] setTargetLiquidity #
           - modifiers: authorized
        - [Ext] manualSync #
        - [Ext] setLP #
           - modifiers: onlyOwner
        - [Ext] setMaster #
           - modifiers: onlyOwner
        - [Ext] isNotInSwap
        - [Ext] checkSwapThreshold
        - [Ext] setDistributionCriteria #
           - modifiers: authorized
        - [Ext] setDistributorSettings #
           - modifiers: authorized
        - [Pub] getCirculatingSupply
        - [Pub] getLiquidityBacking
        - [Pub] isOverLiquified
        - [Ext] checkMaxWalletToken
        - [Ext] checkMaxTxAmount
        - [Ext] setMaxWalletPercent_base1000 #
           - modifiers: onlyOwner
        - [Ext] setMaxTxPercent_base1000 #
           - modifiers: onlyOwner
        - [Ext] multiTransfer #
           - modifiers: onlyOwner
        - [Ext] multiTransfer_fixed #
           - modifiers: onlyOwner