CertiK reviewed NetMind (NetMind-Audit) on 4 Mar 2024: 42 findings, 0 critical; 28 marked fixed, 4 acknowledged, 10 open.
Report hosted on skynet.certik.com.
Trustblock does not review code.
Statuses are the security firm’s own, from its report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 0 | 2 | 5 |
| Medium | 0 | 2 | 4 |
| Low | 10 | 0 | 19 |
The `updateMapping()` function is used to update node and wallet information. The new address `_newAddr`, `_walAddr` information is not updated in the `nodeAddrSta` mapping. ```solidity=216 require(!nodeAddrSta[_walAddr] && nodeIdByAddr[_walAddr] == address(0) && nodeAddrById[_walAddr] == address(0), "walAddr exist"); walletById[_nodeId] = _walAddr; ```
The `CommunityFund` contract is designed for locking NMT assets, which is reserved for the NetMind DAO community, for 5 years. The current code flaw is that `CommunityFund` contract cannot receive NMT assets because the non-payable `fallback()` function definition. `fallback()` is a special function that is executed either when 1. a function that does not exist is called or 2. NMT is sent directly to a contract but `receive()` does not exist or msg.data is not empty ```solidity=167 fallback() external{ } ``` A similar issue also exists in `RewardPool` and `TechnologyFund` contracts. But we find the `receive()` exists in `proxy` contract. We want to know if the contract is upgradeable.
The `deleteNodeAddr()` function is intended to allow the contract owner to remove node information. However, it does not validate whether the node currently holds assets deposited by the user.
When transferring deflationary ERC20 tokens, the input amount may not be equal to the received amount due to the charged transaction fee. For example, if a user sends 100 deflationary tokens (with a 10% transaction fee), only 90 tokens actually arrived to the contract. However, a failure to discount such fees may allow the same user to withdraw 100 tokens from the contract, which causes the contract to lose 10 tokens in such a transaction.
USDT is a non-standard ERC20 token, its `transfer` and `transferFrom` functions do not yield a return value. If the input token refers to USDT, any attempt to transfer USDT using these functions will result in a revert.
```solidity=539 function addNodeStake(uint256 _nodeAddrIndex) internal { for (uint256 i = _nodeAddrIndex; i > 1; i--) { address _nodeAddr = nodeIndexAddr[i]; uint256 _prefixIndex = i - 1; address prefixAddr = nodeIndexAddr[_prefixIndex]; uint256 _nodeSum = nodeStakeAmount[_nodeAddr]; uint256 _prefixSum = nodeStakeAmount[prefixAddr]; if (_prefixSum < _nodeSum){ nodeAddrIndex[prefixAddr] = i; nodeAddrIndex[_nodeAddr] = _prefixIndex; nodeIndexAddr[i] = prefixAddr; nodeIndexAddr[_prefixIndex] = _nodeAddr; }else{ break; } } } ``` The `addNodeStake()` function is intended to sort nodes based on their stake amounts. However, since only pre-existing nodes can stake, the stake amount for a newly added node is always zero. Therefore, the `addNodeStake()` function call at line 237 is unnecessary. ```solidity=237 addNodeStake(_nodeAddrIndex); ```
The `CrossChain` contract is designed to streamline token transfers across the NetMind and BSC chains. However, when traders call the `transferToken()` function, it's possible for users to receive tokens that don't correspond to the original chain.
`transferOwnership()` sets the new `owner` without guaranteeing they are able to actuate transactions on-chain.
The `_transferToken()` function is intended for releasing assets to users on an external blockchain, such as the BNB chain. According to the code logic specified in lines 11 to 13, when users stake NMT on the NetMind main chain, the token assets mapped with a status of 1 will be transferred to the designated receiver. ```solidity=385 function _transferToken(address[2] memory addrs, uint256[2] memory uints, string[] memory strs) internal { if(mainChainSta){ require(address(this).balance >= uints[0], "Insufficient amount of balance"); payable(addrs[0]).transfer(uints[0]); }else { require( tokenSta[addrs[1]] >0 , "Crosschain: The token does not support transfers"); IERC20 token = IERC20(addrs[1]); if(tokenSta[addrs[1]] == 1){ require(token.transfer(addrs[0], uints[0]), "Token transfer failed"); }else{ require(token.mint(addrs[0], uints[0]), "Token transfer failed"); } } emit TransferToken(addrs[0], addrs[1], uints[0], strs[0], strs[1]); } ```
When claiming a reward, it is necessary for the `FixedLock` contract's NMT balance to exceed the total locked NMT assets. This ensures that the user deposited assets cannot be utilized as rewards distributed to users. So there is a distinct resource for reward assets. ```solidity=177 require(address(this).balance - reward >= totalLocked, "reward allocation exceeded"); ```
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (19)
1,044 projects reviewed · 1,375 reports · latest May 2025
See CertiK’s auditsSomething wrong on this page? A missing report, a wrong date, a finding that was fixed since. Tell us and we check it against its source.
Tell us