Metaverse Capital - Smart Contract Audit Report

Summary

Metaverse Capital Audit Report Metaverse Capital ($MVC) is a new ERC20 token on the Ethereum Blockchain.

We reviewed the MetaverseCapital contract at 0x5aC525D33fFDA012eA2Fe246a0Ee698F861304D7 on the Ethereum mainnet.

Notes on the Contract:
  • The total supply of the token is set to 1 billion $MVC [1,000,000,000].
  • No minting or burn functions are present; though the circulating supply can be reduced by sending tokens to the 0x..dead address, if desired.
  • At the time of writing this report, 28.98% of the total supply is in Uniswap liquidity.
  • Of that liquidity, 99% of the LP tokens are stored in a Unicrypt token locking contract and will vest to the team on June 1st, 2022.
  • 24.91% of the total supply is stored in a Unicrypt token vesting contract.
  • 5.74% of the total supply belongs to the team's Treasury wallet.
  • The next five holders own a cumulative 10.9% of the total supply.

  • The owner must manually enable trading in order for trading to take place on the platform. Only accounts that are excluded from fees can trade when trading is set to disabled. Once trading is enabled, it can never be disabled.
  • There is a treasury fee on all transactions for any non-excluded address that participates in a transfer with Uniswap. A separate fee structure can be set by the team to apply a different fee percentage depending on whether the user is buying or selling during the transfer.
  • The tokens collected from the treasury fee are stored in the contract address balance. Once a threshold value of 500,000 tokens (0.05% of the total supply) is met, the tokens are swapped for ETH and sent to the team's Treasury wallet.
  • Although logic for a tax fee, liquidity fee, and buyback fee exists in the contract, these fee percentages are set to 0 and cannot be changed. As a result, automatic liquidity adds and frictionless fee redistribution are not supported by the protocol.
  • The amount of gas per transaction when buying from Uniswap must not exceed the gas price limit of at least 300 Gwei set by the team.
  • Although the Safemath library is utilized, the contract is deployed with Solidity v0.8.9 which has built-in overflow checks. Safemath could be safely removed to reduce contract size and increase gas savings.
  • Some gas optimizations can be achieved through declaring functions external instead of public, and some variables that could be declared constant. As the contract is already deployed, this is merely informational.

  • Ownership Controls:
  • The owner can modify the treasury fee for both buy and sell fee structures. The buy fee cannot exceed 20% and the sell fee cannot exceed 30%.
  • The owner can exclude and include accounts from the treasury fee.
  • The owner can set and update a maximum sell amount and maximum buy amount, which will impose a limit to the number of tokens that can be sold or bought via Uniswap. The owner can also exclude accounts from this restriction.
  • The owner can update the gas price limit to any value greater than 300 Gwei. The owner can also enable/disable this gas limit restriction.
  • The owner can utilize the buyBackTokens() function to swap any amount of ETH in the contract for $MVC tokens and subsequently send those tokens to the burn address.
  • The owner can withdraw any ERC20 tokens erroneously sent to the contract.
  • The owner can airdrop any amount of tokens to any address at any time. A for loop is used to transfer funds for the airdrop; The team must ensure the maximum number of addresses that can be involved in a single airdrop is no more than 350 to prevent this loop from hitting the block gas limit.
  • The owner can enable/disable the automatic swapping functionality at any time.
  • The owner can update the team's Treasury wallet to any addresses at any time.
  • The owner can update the Automated Market Maker Pair contract address at any time.
  • The owner can use the "lock" function in order to temporarily set ownership to address(0). Ownership is restored after the duration of time determined by the owner has passed and they use the 'unlock' function.
  • The unlock function has the potential to be used after ownership is renounced, which will restore ownership to the original owner that initially created the ownership lock. This can be used in a nefarious way by the project team to restore ownership and change fee structures.
  • We recommend that the unlock function is modified to set the "previous owner" = "address(0)" at the end of the unlock function to prevent it from being used more than once per lock.
Audit Findings Summary
  • No external threats were identified.
  • The protocol does not support automatic liquidity adds or frictionless fee redistribution although logic for it exists in the contract.
  • Please ensure trust in the team as they have notable control in the ecosystem.
  • Date: December 16th, 2021

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Storage WriteN/APASS
Arbitrary JumpN/APASS
Centralization of ControlThe owner can set total buy fees up to 20% and total sell fees up to 30%.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
Multiple SendsN/APASS
OraclesN/APASS
SuicideN/APASS
State Change External CallsN/APASS
Unbounded LoopN/APASS
Unchecked RetvalN/APASS
User Supplied AssertionN/APASS
Critical Solidity CompilerN/APASS
Overall Contract Safety PASS

Function Graph

ERC20 Token Graph


Inheritance Chart

Multi-file Token


Functions Overview


 ($) = payable function
 # = non-constant function
 
 +  Context 
    - [Int] _msgSender
    - [Int] _msgData

 + [Int] IERC20 
    - [Ext] totalSupply
    - [Ext] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Ext] approve #
    - [Ext] transferFrom #

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

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Prv] _functionCallWithValue #

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

 + [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] 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 #

 +  MetaverseCapital (Context, IERC20, Ownable)
    - [Pub]  ($)
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals
    - [Ext] totalSupply
    - [Pub] balanceOf
    - [Ext] transfer #
    - [Ext] allowance
    - [Pub] approve #
    - [Ext] transferFrom #
    - [Ext] increaseAllowance #
    - [Ext] decreaseAllowance #
    - [Ext] isExcludedFromReward
    - [Ext] totalFees
    - [Pub] enableTrading #
       - modifiers: onlyOwner
    - [Ext] minimumTokensBeforeSwapAmount
    - [Pub] setAutomatedMarketMakerPair #
       - modifiers: onlyOwner
    - [Prv] _setAutomatedMarketMakerPair #
    - [Ext] setProtectionSettings #
       - modifiers: onlyOwner
    - [Ext] setGasPriceLimit #
       - modifiers: onlyOwner
    - [Ext] disableTransferDelay #
       - modifiers: onlyOwner
    - [Ext] reflectionFromToken
    - [Ext] airdropToWallets #
       - modifiers: onlyOwner
    - [Ext] removeLimits #
       - modifiers: onlyOwner
    - [Pub] tokenFromReflection
    - [Pub] excludeFromReward #
       - modifiers: onlyOwner
    - [Ext] updateMaxBuyAmount #
       - modifiers: onlyOwner
    - [Ext] updateMaxSellAmount #
       - modifiers: onlyOwner
    - [Pub] excludeFromMaxTransaction #
       - modifiers: onlyOwner
    - [Pub] includeInReward #
       - modifiers: onlyOwner
    - [Prv] _approve #
    - [Prv] _transfer #
    - [Prv] swapBack #
       - modifiers: lockTheSwap
    - [Prv] swapTokensForETH #
    - [Prv] addLiquidity #
    - [Prv] _tokenTransfer #
    - [Prv] _transferStandard #
    - [Prv] _transferToExcluded #
    - [Prv] _transferFromExcluded #
    - [Prv] _transferBothExcluded #
    - [Prv] _reflectFee #
    - [Prv] _getValues
    - [Prv] _getTValues
    - [Prv] _getRValues
    - [Prv] _getRate
    - [Prv] _getCurrentSupply
    - [Prv] _takeLiquidity #
    - [Prv] calculateTaxFee
    - [Prv] calculateLiquidityFee
    - [Prv] removeAllFee #
    - [Prv] restoreAllFee #
    - [Ext] isExcludedFromFee
    - [Ext] excludeFromFee #
       - modifiers: onlyOwner
    - [Ext] includeInFee #
       - modifiers: onlyOwner
    - [Ext] setBuyFee #
       - modifiers: onlyOwner
    - [Ext] setSellFee #
       - modifiers: onlyOwner
    - [Ext] setTreasuryAddress #
       - modifiers: onlyOwner
    - [Ext] setLiquidityAddress #
       - modifiers: onlyOwner
    - [Pub] setSwapAndLiquifyEnabled #
       - modifiers: onlyOwner
    - [Ext] buyBackTokens #
       - modifiers: onlyOwner
    - [Ext] launch #
       - modifiers: onlyOwner
    - [Ext] launchWithoutAirdrop #
       - modifiers: onlyOwner
    - [Prv] transferToAddressETH #
    - [Ext]  ($)
    - [Ext] transferForeignToken #
       - modifiers: onlyOwner