MIND Token

Smart Contract Audit Report

Audit Summary

MIND Token Audit Report BiggerMINDS is building a new ERC-20 token with automatic liquidity adds and a reward system based on Nodes.

For this audit, we reviewed the project team's Mind and NODERewardManagement contract at 0x9867cc2419Fb317e986A648E02cF7C35aa87a336 on Avalanche.

Audit Findings

Please ensure trust in the team prior to investing as they have substantial control in the ecosystem.
Date: February 11th, 2022.
Updated: February 14th, 2022 to reflect the contract's mainnet deployment and to update token allocation.

Finding #1 - NODERewardManagement - High (Resolved)

Description: The _transferNode() function removes the Nodes from the sender's list of Nodes and replaces the slot in the array with the last Node in the list. The Node being transferred is added to the end of the recipient's array of Nodes. However, as the contract uses binary search to locate specific Nodes, the Nodes must be added to the list sorted in order of creation time.
Risk/Impact: The Nodes are not being added to the list with respect to order of creation time, so the binary search will fail every time.
Recommendation: Ensure that the Nodes are sorted in order of creation time.
Resolution: The team has opted to use linear search rather than binary search, which does not rely on the Nodes being in sorted order.

Finding #2 - MIND - Informational (Resolved)

Description: Several functions are declared public, but are never called internally.
NODERewardManagement: _getNodeNumberOf(address)
Mind: updateUniswapV2Router, setAutomatedMarketMakerPair, cashoutReward, compound, changeSwapLiquify, getNodeNumberOf, getRewardAmountOf, getRewardAmount, changeNodePrice, getNodePrice, changeRewardPerNode, getRewardPerNode, changeClaimTime, getClaimTime, changeAutoDistri, getAutoDistri, changeGasDistri, getGasDistri, getDistriCount, getNodesNames, getNodesCreatime, getNodesRewards, getNodesLastClaims, distributeRewards, publiDistriRewards, getTotalStakedReward, getTotalCreatedNodes
Recommendation: These functions should be declared external for additional gas savings on each call.
Resolution: The team has implemented the above recommendation.

Finding #3 - NODERewardManagement - Informational (Resolved)

Description: The lastDistributionCount state variable can never be modified, but is not declared constant.
Recommendation: This state variable can be declared constant for additional gas savings on each call.
Resolution: The team has implemented the above recommendation.

Contracts Overview

Mind Contract:
  • The total supply of the token is set to 250 million $MIND.
  • No mint or burn functions exist, though the circulating supply can be decreased by sending tokens to the 0x..dead address.
  • At the time of writing this report, there are 435 total token holdres. The token allocation is as follows:

  • Blacklisted addresses are not are not permitted to participate in transfers.
  • Users who are included in fees must own a Node in the NODERewardManagement contract in order to perform a sell transaction.
  • There is a fee charged on transfers in which the sender is selling tokens to Uniswap; this fee does not apply to senders who are excluded from fees.
  • The tokens collected through the sell fee are transferred to the Cashout pool wallet controlled by the team.

  • Anyone can use this contract to create a new Node in the NODERewardManagement contract.
  • Users must pay the node price determined by the project team.
  • The tokens collected through node sales are stored in the contract.
  • During Node purchases, once a threshold value of tokens in the contract is met, a portion is swapped for AVAX and transferred to the expense pool controlled by the team.
  • Another portion is swapped for AVAX and transferred to the Distribution pool controlled by the team.
  • Another portion is retained as tokens and transferred to the Distribution pool.
  • Another portion is used to fund JoeSwap liquidity; half of the tokens allocated for liquidity are sold for AVAX, paired with the remaining half of the tokens, and added as liquidity to the AVAX pair.
  • Another portion is swapped for AVAX and transferred to the marketing pool wallet.
  • Any remaining tokens are swapped for AVAX and stored in the contract balance.

  • Anyone can use this contract to claim their Node rewards; users can choose to claim all rewards from all Nodes in a single transaction, claim only a specific amount of rewards across one or more Nodes, or claim only the rewards from a specific Node.
  • Rewards are calculated within the NODERewardManagement contract and supplied from the Distribution pool wallet.
  • Users can also choose to compound their all or a portion of their Node rewards, which creates a new Node for the user at execution time.
  • Users can use this contract to rename their Node to any string between 3 and 32 bytes.
  • Anyone can transfer their Node to any address at any time.
  • Anyone can trigger the reward distribution for all users' Nodes at any time.
  • Blacklisted addresses, the Expense pool address, and the Distribution pool address are not allowed to create Nodes or claim Node rewards at any time.

  • The owner can set the NODERewardManagement contract address to any address at any time.
  • The owner can set the Uniswap Router and Pair addresses at any time.
  • The owner can set the threshold value required for swaps to any value at any time.
  • The owner can set the Expense pool, Distribution pool, Marketing pool, and Cashout pool addresses to any address at any time.
  • The owner can set the sell fee to any value at any time.
  • The owner can set the liquidity, expense, marketing, and reward fund allocations to any value at any time.
  • The owner can add or remove any user from the blacklist at any time.
  • The owner can exclude any address from fees at any time.
  • The owner can withdraw any ETH from the contract at any time.
  • The owner can disable the automatic liquidity adds at any time.
  • The owner can use this contract to changes several properties on the NODERewardManagement contract including the node price, reward-per-node rate, wait time between claims, and toggle auto distribution.
  • The owner can also use this contract to automatically distribute rewards on the NODERewardManagement contract.

  • The contract complies with the ERC-20 standard.
  • As the contract is implemented with Solidity v0.8.0, they are safe from any possible overflows/underflows.
NODERewardManagement Contract:
  • This contract is used to manage the Node rewards for the $MIND token; no token transfers occur within this contract.
  • All functions in this contract can only be accessed by the Mind contract or the "gate keeper"; the gate keeper address is set as the deployer's address on initialization.
  • It is intended that the functionality of this contract will only be triggered by the token contract in appropriate circumstances, but as the owner also has access to each of the functions, it is possible that the data can be updated without performing any token transfers.
  • The owner or token contract can use this contract to Create a node at any time.
  • Upon creating a Node, if auto-distribution is enabled, the function will process the list of Node holders in order to distribute rewards to as many as is permitted.
  • Once rewards are distributed, they will need to be claimed.
  • The owner or token contract can reset any Node's available rewards at any time.
  • The contract contains the appropriate functions so that the token contract may correctly update the Node data as needed.
  • The owner can change the node price at any time.
  • The owner can change the reward-per-node rate at any time.
  • The owner can change the wait time between reward claims at any time.
  • The owner can change the amount of gas allocated to reward distributions at any time.
  • The token contract or owner can manually trigger the function to distribute rewards at any time.
  • As the contract is implemented with Solidity v0.8.0, they are safe from any possible overflows/underflows.

Audit Results

Vulnerability CategoryNotesResult
Arbitrary Jump/Storage WriteN/APASS
Centralization of Control
  • The owner can change the Distribution wallet address at any time, thus funding rewards with other users' tokens.
  • The fees are uncapped and can be set to up to 100% at any time.
  • The owner can blacklist any user at any time.
  • The owner can directly manipulate Node data via the NODERewardManagement contract.
WARNING
Compiler IssuesN/APASS
Delegate Call to Untrusted ContractN/APASS
Dependence on Predictable VariablesN/APASS
Ether/Token TheftN/APASS
Flash LoansN/APASS
Front RunningN/APASS
Improper EventsN/APASS
Improper Authorization SchemeN/APASS
Integer Over/UnderflowN/APASS
Logical IssuesN/APASS
Oracle IssuesN/APASS
Outdated Compiler VersionN/APASS
Race ConditionsN/APASS
ReentrancyN/APASS
Signature IssuesN/APASS
Unbounded LoopsN/APASS
Unused CodeN/APASS
Overall Contract Safety PASS

Inheritence Chart

Smart Contract Audit - Inheritance

Function Graph

Smart Contract Audit - Graph

Functions Overview


 ($) = payable function
 # = non-constant function
 
 Int = Internal
 Ext = External
 Pub = Public

 + [Lib] SafeMathUint 
    - [Int] toInt256Safe

 + [Lib] SafeMathInt 
    - [Int] mul
    - [Int] div
    - [Int] sub
    - [Int] add
    - [Int] abs
    - [Int] toUint256Safe

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

 + [Lib] IterableMapping 
    - [Pub] get
    - [Pub] getIndexOfKey
    - [Pub] getKeyAtIndex
    - [Pub] size
    - [Pub] set #
    - [Pub] remove #

 + [Lib] Address 
    - [Int] isContract
    - [Int] sendValue #
    - [Int] functionCall #
    - [Int] functionCall #
    - [Int] functionCallWithValue #
    - [Int] functionCallWithValue #
    - [Int] functionStaticCall
    - [Int] functionStaticCall
    - [Int] functionDelegateCall #
    - [Int] functionDelegateCall #
    - [Int] verifyCallResult

 + [Int] IJoeRouter01 
    - [Ext] factory
    - [Ext] WAVAX
    - [Ext] addLiquidity #
    - [Ext] addLiquidityAVAX ($)
    - [Ext] removeLiquidity #
    - [Ext] removeLiquidityAVAX #
    - [Ext] removeLiquidityWithPermit #
    - [Ext] removeLiquidityAVAXWithPermit #
    - [Ext] swapExactTokensForTokens #
    - [Ext] swapTokensForExactTokens #
    - [Ext] swapExactAVAXForTokens ($)
    - [Ext] swapTokensForExactAVAX #
    - [Ext] swapExactTokensForAVAX #
    - [Ext] swapAVAXForExactTokens ($)
    - [Ext] quote
    - [Ext] getAmountOut
    - [Ext] getAmountIn
    - [Ext] getAmountsOut
    - [Ext] getAmountsIn

 + [Int] IJoeRouter02 (IJoeRouter01)
    - [Ext] removeLiquidityAVAXSupportingFeeOnTransferTokens #
    - [Ext] removeLiquidityAVAXWithPermitSupportingFeeOnTransferTokens #
    - [Ext] swapExactTokensForTokensSupportingFeeOnTransferTokens #
    - [Ext] swapExactAVAXForTokensSupportingFeeOnTransferTokens ($)
    - [Ext] swapExactTokensForAVAXSupportingFeeOnTransferTokens #

 + [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] IJoeFactory 
    - [Ext] feeTo
    - [Ext] feeToSetter
    - [Ext] migrator
    - [Ext] getPair
    - [Ext] allPairs
    - [Ext] allPairsLength
    - [Ext] createPair #
    - [Ext] setFeeTo #
    - [Ext] setFeeToSetter #
    - [Ext] setMigrator #

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

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

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

 + [Int] IERC20Metadata (IERC20)
    - [Ext] name
    - [Ext] symbol
    - [Ext] decimals

 +  ERC20 (Context, IERC20, IERC20Metadata)
    - [Pub]  #
    - [Pub] name
    - [Pub] symbol
    - [Pub] decimals
    - [Pub] totalSupply
    - [Pub] balanceOf
    - [Pub] transfer #
    - [Pub] allowance
    - [Pub] approve #
    - [Pub] transferFrom #
    - [Pub] increaseAllowance #
    - [Pub] decreaseAllowance #
    - [Int] _transfer #
    - [Int] _mint #
    - [Int] _burn #
    - [Int] _approve #
    - [Int] _beforeTokenTransfer #

 + [Lib] SafeERC20 
    - [Int] safeTransfer #
    - [Int] safeTransferFrom #
    - [Int] safeApprove #
    - [Int] safeIncreaseAllowance #
    - [Int] safeDecreaseAllowance #
    - [Prv] _callOptionalReturn #

 +  PaymentSplitter (Context)
    - [Pub]  ($)
    - [Ext]  ($)
    - [Pub] totalShares
    - [Pub] totalReleased
    - [Pub] totalReleased
    - [Pub] shares
    - [Pub] released
    - [Pub] released
    - [Pub] payee
    - [Pub] release #
    - [Pub] release #
    - [Prv] _pendingPayment
    - [Prv] _addPayee #

 +  NODERewardManagement 
    - [Pub]  #
    - [Ext] setToken #
       - modifiers: onlySentry
    - [Prv] distributeRewards #
    - [Ext] createNode #
       - modifiers: onlySentry
    - [Prv] isNameAvailable
    - [Int] _burn #
    - [Prv] _getNodeByName
    - [Prv] _getNodeWithCreatime
    - [Prv] binary_search
    - [Ext] _cashoutNodeReward #
       - modifiers: onlySentry
    - [Ext] _cashoutAllNodesReward #
       - modifiers: onlySentry
    - [Prv] claimable
    - [Ext] _getRewardAmountOf
    - [Ext] _getRewardAmountOf
    - [Ext] _getNodeRewardAmountOf
    - [Ext] _getNodesNames
    - [Ext] _getNodesCreationTime
    - [Ext] _getNodesRewardAvailable
    - [Ext] _getNodesLastClaimTime
    - [Int] uint2str
    - [Ext] _changeNodePrice #
       - modifiers: onlySentry
    - [Ext] _changeRewardPerNode #
       - modifiers: onlySentry
    - [Ext] _changeClaimTime #
       - modifiers: onlySentry
    - [Ext] _changeAutoDistri #
       - modifiers: onlySentry
    - [Ext] _changeGasDistri #
       - modifiers: onlySentry
    - [Pub] _getNodeNumberOf
    - [Prv] isNodeOwner
    - [Ext] _isNodeOwner
    - [Ext] _distributeRewards #
       - modifiers: onlySentry
    - [Ext] _transferNode #
       - modifiers: onlySentry

 +  Mind (ERC20, Ownable, PaymentSplitter)
    - [Pub]  #
       - modifiers: ERC20,PaymentSplitter
    - [Ext] setNodeManagement #
       - modifiers: onlyOwner
    - [Pub] updateUniswapV2Router #
       - modifiers: onlyOwner
    - [Ext] updateSwapTokensAmount #
       - modifiers: onlyOwner
    - [Ext] updateExpenseWall #
       - modifiers: onlyOwner
    - [Ext] updateRewardsWall #
       - modifiers: onlyOwner
    - [Ext] updateMarketingWall #
       - modifiers: onlyOwner
    - [Ext] updateCashoutWall #
       - modifiers: onlyOwner
    - [Ext] updateRewardsFee #
       - modifiers: onlyOwner
    - [Ext] updateLiquiditFee #
       - modifiers: onlyOwner
    - [Ext] updateFuturFee #
       - modifiers: onlyOwner
    - [Ext] updateMarketingFee #
       - modifiers: onlyOwner
    - [Ext] updateSellFee #
       - modifiers: onlyOwner
    - [Ext] updateRwSwapFee #
       - modifiers: onlyOwner
    - [Pub] setAutomatedMarketMakerPair #
       - modifiers: onlyOwner
    - [Ext] blacklistMalicious #
       - modifiers: onlyOwner
    - [Ext] setExcludedFromFee #
       - modifiers: onlyOwner
    - [Prv] _setAutomatedMarketMakerPair #
    - [Pub] transfer #
    - [Pub] transferFrom #
    - [Int] _transfer #
    - [Prv] swapAndSendToFee #
    - [Prv] swapAndLiquify #
    - [Prv] swapTokensForEth #
    - [Prv] addLiquidity #
    - [Pub] createNodeWithTokens #
    - [Pub] cashoutReward #
    - [Pub] cashoutAll #
    - [Pub] compound #
    - [Pub] boostReward #
       - modifiers: onlyOwner
    - [Pub] changeSwapLiquify #
       - modifiers: onlyOwner
    - [Pub] getNodeNumberOf
    - [Pub] getRewardAmountOf
       - modifiers: onlyOwner
    - [Pub] getRewardAmount
    - [Pub] changeNodePrice #
       - modifiers: onlyOwner
    - [Pub] getNodePrice
    - [Pub] changeRewardPerNode #
       - modifiers: onlyOwner
    - [Pub] getRewardPerNode
    - [Pub] changeClaimTime #
       - modifiers: onlyOwner
    - [Pub] getClaimTime
    - [Pub] changeAutoDistri #
       - modifiers: onlyOwner
    - [Pub] getAutoDistri
    - [Pub] changeGasDistri #
       - modifiers: onlyOwner
    - [Pub] getGasDistri
    - [Pub] getDistriCount
    - [Pub] getNodesNames
    - [Pub] getNodesCreatime
    - [Pub] getNodesRewards
    - [Pub] getNodesLastClaims
    - [Ext] transferNode #
    - [Pub] distributeRewards #
       - modifiers: onlyOwner
    - [Pub] publiDistriRewards #
    - [Pub] getTotalStakedReward
    - [Pub] getTotalCreatedNodes