Many Worlds Token - Audit Report

Summary

ManyWorldsToken Audit Report Many Worlds is building a BEP-20 token with automatic liquidity adds that rewards holders with dividends in BUSD.

For this audit, we reviewed the project team's ManyWorlds and HolderRewarderDistributor contracts at commit 3f500524e7e3ee1b0d420cbfb034e9a4425c69f8 on the team's private Github repository.

Notes on the Contracts:
ManyWorlds Contract:
  • The total supply of the token is initially set to 5 billion.
  • No mint functions are present beyond deployment.
  • Authorized addresses can burn their own tokens to reduce the total supply at any time.
  • Anyone can reduce the circulating supply by sending tokens to the 0x..dead address.
  • Initially, 100% of the total supply is held by the owner.

  • There is a maximum transaction amount enforced on all sell transactions with Pancakeswap; this does not apply to the owner, or during transactions where the sender is excluded from this restriction.
  • The contract features a locking mechanism that prevents users from transferring portions of their token balance until the lock time has elapsed.
  • There is a long-term holder fee, a mid-term holder fee, an operations fee, a burn fee, a lotto fee, and a liquidity fee on all transfers where neither the sender nor the recipient is excluded from fees.
  • There is a different fee structure that applies to different portions of the tokens being transferred based on category they fall in to (standard, mid, or long term) and whether it's a buy or sell transaction. The tokens are categorized based on the amount of time the user has held them.
  • The tokens collected through the operations fee are sent to the operations wallet address controlled by the team.
  • The tokens collected through the lotto fee are sent to the lotto wallet address controlled by the team.
  • The tokens collected through the burn fee are sent to the burn address.
  • The tokens collected through the long-term and mid-term holder fees are stored in the contract, and once a threshold value of 1.5 million $MANY tokens is met, the tokens are swapped for BNB and sent to the Distributor contract to be distributed as dividends amongst eligible token holders.
  • The tokens collected through the liquidity fee are stored in the contract, and once a threshold value of 2.5 million $MANY tokens is met, they are used to fund Pancakeswap liquidity.
  • Liquidity-adds are funded by selling half of the tokens collected as liquidity fees, pairing the received BNB with the token, and adding it as liquidity to the BNB pair.
  • The newly created LP tokens are stored in the owner's wallet address. We recommend that this liquidity is locked at the time of acquisition.

  • Once dividends are distributed, they will need to be claimed.
  • Dividend rewards can be claimed when the team kicks off the claim cycle, which will process all eligible token holders.
  • Users can also process their own claim at any time.
  • Claimed dividends are sent to the user's wallet address.

  • The owner can prevent any user from sending or receiving tokens at any time.
  • The owner can include or exclude any address from fees at any time.
  • The owner can include or exclude any address from rewards at any time.
  • The owner can include or exclude any address from the max transaction amount restriction at any time.
  • The owner can toggle the burn fee at any time.
  • The owner can enable or disable automatic liquidity adds at any time.
  • The owner can grant Authorization to any address at any time.
  • Authorized addresses can lock any portion of a user's tokens at any time, even if they do not have them in their balance. Every 90 days, 15% of the locked tokens are unlocked.
  • Authorized addresses can use this contract to call the snapshotTotalShares function on the Distributor contract.
  • Authorized addresses can use this contract to process rewards on the Distributor contract.
  • Authorized addresses can use this contract to swap the $MANY tokens in the lotto address for BUSD.
  • Authorized addresses can use this contract to swap the $MANY tokens in the operations address for BUSD.
  • Authorized addresses can set the Pancakeswap router address, the Operations address, the Lotto address, the Distributor contract address to any address at any time.
  • Authorized addresses can set the maximum transaction limit to any value at any time.
  • Authorized addresses can set the long-term tax fee up to 1.5%, the mid-term tax fee up to 4.5%, the operational fee up to 2%, the burn fee up to 1%, the lotto fee up to 1%, and the liquidity fee up to 1%.
HolderRewarderDistributor Contract:
  • This contract is used to keep track of all Many Worlds token transfers for the purposes of taking fees and distributing rewards.
  • When a user receives $MANY tokens, the user is added as a Shareholder in the HolderRewarderDistributor contract and a record of the transfer is stored; the transfer amount and the transaction timestamp are recorded.
  • When a user sends $MANY tokens, the contract locates the user's latest transactions in order to fulfill the amount the user intends to transfer. The latest records are used first in an effort to reward long-term holders as much as possible.
  • This contract is also used to record a snapshot of how many tokens have been held for between 7 and 90 days (mid-term holds), and how many tokens have been held for more than 90 days (long-term holds).
  • The contract relies on this snapshot data when processing rewards for shareholders, so it is the responsibility of the project team to ensure that a snapshot is taken before distributing dividends so that all qualified holders can benefit.
  • The contract distributes dividends from a fund for long-term hold dividends and another fund for mid-term hold dividends.
Notes Across All Contracts:
  • The team has worked with us to reduce their level of control and address logical and gas-related issues within the contracts.
  • Some state variables could have been declared constant and some functions could have been declared external for extra gas savings.
  • Although the SafeMath library is utilized, the contract is implemented with Solidity v0.8.10 which has built-in overflow checks. SafeMath could be safely removed to reduce contract size and increase gas savings.
  • The token contract complies with the ERC20 standard.

Audit Findings Summary:
  • No security issues from outside attackers were identified.
  • As with any presale, ensure trust in the team prior to investing.
  • Further, ensure trust in the team as they have notable control in the ecosystem.
  • Date: December 17th, 2021

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of ControlN/APASS
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
Multiple SendsN/APASS
OraclesN/APASS
SuicideN/APASS
State Change External CallsN/APASS
Unbounded LoopsN/APASS
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

ERC20 Token Graph

Contract Inheritance


 ($) = payable function
 # = non-constant function
 
 + [Int] IBEP20 
    - [Ext] totalSupply
    - [Ext] decimals
    - [Ext] symbol
    - [Ext] name
    - [Ext] getOwner
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

 + [Int] IUniswapV2Factory 
    - [Ext] feeTo
    - [Ext] feeToSetter
    - [Ext] getPair
    - [Ext] allPairs
    - [Ext] allPairsLength
    - [Ext] createPair #
    - [Ext] setFeeTo #
    - [Ext] setFeeToSetter #

 + [Int] IUniswapV2Pair 
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transfer #
    - [Ext] transferFrom #
    - [Ext] DOMAIN_SEPARATOR
    - [Ext] PERMIT_TYPEHASH
    - [Ext] nonces
    - [Ext] permit #
    - [Ext] MINIMUM_LIQUIDITY
    - [Ext] factory
    - [Ext] token0
    - [Ext] token1
    - [Ext] getReserves
    - [Ext] price0CumulativeLast
    - [Ext] price1CumulativeLast
    - [Ext] kLast
    - [Ext] mint #
    - [Ext] burn #
    - [Ext] swap #
    - [Ext] skim #
    - [Ext] sync #
    - [Ext] initialize #

 + [Int] IUniswapV2Router01 
    - [Ext] factory
    - [Ext] WETH
    - [Ext] addLiquidity #
    - [Ext] addLiquidityETH ($)
    - [Ext] removeLiquidity #
    - [Ext] removeLiquidityETH #
    - [Ext] removeLiquidityWithPermit #
    - [Ext] removeLiquidityETHWithPermit #
    - [Ext] swapExactTokensForTokens #
    - [Ext] swapTokensForExactTokens #
    - [Ext] swapExactETHForTokens ($)
    - [Ext] swapTokensForExactETH #
    - [Ext] swapExactTokensForETH #
    - [Ext] swapETHForExactTokens ($)
    - [Ext] quote
    - [Ext] getAmountOut
    - [Ext] getAmountIn
    - [Ext] getAmountsOut
    - [Ext] getAmountsIn

 + [Int] IUniswapV2Router02 (IUniswapV2Router01)
    - [Ext] removeLiquidityETHSupportingFeeOnTransferTokens #
    - [Ext] removeLiquidityETHWithPermitSupportingFeeOnTransferTokens #
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactETHForTokensSupportingFeeOnTransferTokens ($)
    - [Ext] swapExactTokensForETHSupportingFeeOnTransferTokens #

 + [Lib] SafeMath 
    - [Int] add
    - [Int] sub
    - [Int] sub
    - [Int] mul
    - [Int] div
    - [Int] div
    - [Int] mod

 +  Authorization 
    - [Pub]  #
    - [Pub] authorize #
       - modifiers: onlyOwner
    - [Pub] unauthorize #
       - modifiers: onlyOwner
    - [Pub] isOwner
    - [Pub] isAuthorized
    - [Pub] transferOwnership #
       - modifiers: onlyOwner

 + [Int] IHolderRewarderDistributor 
    - [Ext] addShare #
    - [Ext] removeShare #
    - [Ext] getTotalShares
    - [Ext] getTotalSharesCount
    - [Ext] totalSharesCount
    - [Ext] snapshotTotalShares #
    - [Ext] getSnapshotTotalShares
    - [Ext] process #
    - [Ext] manualClaim #
    - [Ext] addSupply #
    - [Ext] resetSupply #

 +  HolderRewarderDistributor (IHolderRewarderDistributor)
    - [Pub]  #
    - [Ext] addShare #
       - modifiers: onlyToken
    - [Ext] removeShare #
       - modifiers: onlyToken
    - [Int] amendShareAmount #
    - [Int] amendShareRewardDateTime #
    - [Int] popTopOfStack #
    - [Prv] calculateShareOfShareHolder #
    - [Prv] getTotalShareOfShareHolder
    - [Ext] snapshotTotalShares #
       - modifiers: onlyToken
    - [Ext] getSnapshotTotalShares
    - [Ext] manualClaim #
       - modifiers: onlyToken
    - [Ext] process #
       - modifiers: onlyToken
    - [Int] processShareHolder #
    - [Int] distributeLongDividend #
    - [Int] distributeMidDividend #
    - [Int] addShareholder #
    - [Int] removeShareholder #
    - [Ext] getTotalShares
    - [Pub] getTotalSharesCount
    - [Pub] totalSharesCount
    - [Int] getBlockTimestamp
    - [Int] getMRate
    - [Int] getLRate
    - [Ext] addSupply #
       - modifiers: onlyToken
    - [Ext] resetSupply #
       - modifiers: onlyToken
    - [Ext]  ($)

 +  ManyWorlds (IBEP20, Authorization)
    - [Pub]  #
       - modifiers: Authorization
    - [Int] getBlockTimestamp
    - [Pub] getOwner
    - [Pub] decimals
    - [Pub] symbol
    - [Pub] name
    - [Pub] totalSupply
    - [Pub] rtotalSupply
    - [Pub] balanceOf
    - [Pub] rewardsOf
    - [Pub] rewardCountOf
    - [Pub] shareHolderCount
    - [Pub] getSnapshotTermRewards
    - [Pub] isLocked
    - [Pub] isTxBurn
    - [Pub] lockAccount #
       - modifiers: authorized
    - [Pub] unlockAccount #
       - modifiers: authorized
    - [Pub] includeInFee #
       - modifiers: authorized
    - [Pub] excludeInFee #
       - modifiers: authorized
    - [Pub] includeInRewards #
       - modifiers: authorized
    - [Pub] excludeInRewards #
       - modifiers: authorized
    - [Pub] includeInMxTxAmount #
       - modifiers: authorized
    - [Pub] excludeInMxTxAmount #
       - modifiers: authorized
    - [Pub] getCirculatingSupply
    - [Pub] setTxBurn #
       - modifiers: onlyOwner
    - [Ext] transfer #
    - [Ext] allowance
    - [Pub] addFounder #
       - modifiers: authorized
    - [Pub] isFounder
    - [Int] checkFounders #
    - [Ext] approve #
    - [Ext] transferFrom #
    - [Pub] increaseAllowance #
    - [Pub] decreaseAllowance #
    - [Int] _transfer #
    - [Pub] _burn #
       - modifiers: authorized
    - [Int] _approve #
    - [Ext]  ($)
    - [Pub] setSwapAndLiquifyEnabled #
       - modifiers: onlyOwner
    - [Prv] swapAndLiquify #
       - modifiers: lockTheSwap
    - [Prv] swapTokensForEth #
    - [Prv] addLiquidity #
    - [Prv] sendBNBToDistributor #
       - modifiers: lockTheSwap
    - [Int] _tokenTransfer #
    - [Prv] _takeOperations #
    - [Prv] _takeRewardFee #
    - [Prv] _takeLottoFee #
    - [Prv] _takeBurn #
    - [Prv] _takeLiquidity #
    - [Int] calculateFeeTier
    - [Prv] calculateFee
    - [Pub] snapshotRewards #
       - modifiers: authorized
    - [Pub] processRewards #
       - modifiers: authorized
    - [Pub] manualClaimRewards #
    - [Ext] depositWallets #
       - modifiers: authorized
    - [Int] swapTokenToBUSD #
    - [Pub] setRouterAddress #
       - modifiers: authorized
    - [Pub] setOperationAddress #
       - modifiers: authorized
    - [Pub] setLottoAddress #
       - modifiers: authorized
    - [Pub] setDistributorAddress #
       - modifiers: authorized
    - [Pub] setMaxTxPercent #
       - modifiers: authorized
    - [Pub] setMaxPercSellAmount #
       - modifiers: authorized
    - [Pub] setTaxFee #
       - modifiers: authorized