tometa72-aduit

CertiKFiles named in the report

CertiK reviewed Tometa72 DAO (tometa72-aduit) on 23 Feb 2024: 13 findings, 1 critical; 12 marked fixed, 1 acknowledged.

1 critical finding, fixed
Open the reportOpen Tometa72 DAO’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings13

Statuses are the security firm’s own, from its report.

SeverityOpenAcknowledgedFixed
Critical001
High012
Medium004
Low005
CriticalNo Token Generation in `Optimized_ERC20.sol` andFixed

No tokens can be generated within the updated files `Optimized_ERC20.sol` and `Optimized_DistributionERC20.sol`. This issue severely impacts the core functionality of the contracts, rendering them ineffective for their intended purpose. In a typical ERC20 token contract, mechanisms for token minting or initial token distribution are crucial to create the circulating supply of the token.

HighCentralization Risks in ERC20.solFixed

In the contract `ERC20` the role `_owner` has authority over the functions shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and set wallets, set `_startTime`, transfer or renounce the ownership, and check wallets. ![](https://accelerator-tasks-prod.acc.corp.certik.com/11ee-8ee9-18eacfb0-868f-87a0fd7916df/diagrams/centralization_ERC20-ERC20-_owner.svg)

HighIncorrect Locked Token Balance CalculationFixed

In the contract `ERC20`, the `_lockBalanceNum()` function is intended to calculate the amount of tokens that are locked in a wallet. The contract's design expects that if a wallet's balance falls below this locked amount, any transfer attempts should be blocked. However, an issue arises in the `_transfer()` function, where a wallet can effectively reduce its locked token amount through unauthorized transfers. This vulnerability stems from a flaw in the `_lockBalanceNum()` function's calculation, which incorrectly allows the locked amount to be influenced by the wallet's actions, rather than strictly adhering to the current timestamp as intended.

MediumInaccurate Token Lock Calculation Due to `lastRelFixed

In the contract `ERC20`, the `_lockBalanceNum()` function is intended to calculate the amount of tokens that are locked in a wallet. The line 751 in the function checks whether `walletRecorde.lastRelease` equals 0 as a means to determine if tokens have been previously released from the wallet. However, a discrepancy arises because `walletRecorde.lastRelease` might be updated before `_startTime`, erroneously indicating that the wallet has already initiated a token release. This premature update can lead to an overestimation of locked tokens, thus locking more tokens in the wallet than intended. ```solidity=750 //初次释放(证明还有初始释放) if (walletRecorde.lastRelease == 0) { ```

MediumPotential Underestimation of Lock Duration in `_lFixed

The `_lockBalanceNum()` function uses the lock duration to calculate the amount of locked tokens. It determines the duration by subtracting the `walletRecorde.lastRelease` timestamp, which represents the time when the wallet last transferred tokens, from the current timestamp (as observed in line 792 of the code). This method, however, may lead to an underestimation of the actual lock duration. The reason is that `walletRecorde.lastRelease` might not accurately reflect the beginning of the lock period. This miscalculation can potentially result in a larger number of tokens being locked than originally planned. ```solidity=792 duration = nowTime.sub(walletRecorde.lastRelease); ```

MediumPremature Token Release Prior to `_startTime`Fixed

In the contract `ERC20`, the `_lockBalanceNum()` function is intended to calculate the amount of tokens that are locked in a wallet. The design intention is that the locked token amount should be 0 if the current timestamp (`nowTime`) is less than the specified `_startTime`. However, the function lacks a crucial check to verify whether `nowTime` is greater than `_startTime`. As a result, this oversight in the code logic leads to the premature release of tokens before the intended `_startTime`.

MediumRisk of Overwriting Wallet Records in `setOrganizFixed

The `setOrganization()` function is responsible for allocating locked tokens to specified wallets. However, the function lacks a check to confirm whether a wallet has been previously set. This omission can lead to the inadvertent overwriting of existing records in `walletRecords[_walletArray[i]]`. Consequently, such overwriting might result in unintended behaviors. For example, most tokens in the wallet could be immediately released since the amount of locked tokens would be updated. ```solidity=428 for (uint256 i = 0; i < _walletArray.length; i++) { orgWallet[_organizationId].push(_walletArray[i]); walletRecords[_walletArray[i]] = WalletRecord( _amountArray[i], _amountArray[i], _organizationId, _firstUnlockPre, _releaseIntervalValue, _intervalTimeValue, _secondUnlockPre, 0, _releaseAllTime ); _transfer(_owner, _walletArray[i], _amountArray[i]); } ```

LowInaccurate Calculation of `_releaseAllTimes` in `Fixed

In the `ERC20` contract, the `_releaseAll()` function is tasked with calculating the timestamp (`_releaseAllTimes`) when all tokens become fully released. However, the calculation in the current code is incorrect. Taking the `orgOne` example, the function erroneously computes `_releaseAllTimes` as `_startTime + (11 * 30 days)`, while the expected outcome should be `_startTime + (10 * 30 days)`. ```solidity=725 uint256 times = (firstBalance.sub(firstBalance.mod(_secondUnlockPre))) .div(_secondUnlockPre); uint256 _releaseAllTimes = _startTime.add(_releaseInterval).add( times.mul(_intervalTime) ); ``` ```solidity uint256[5] orgOne = [200000000 * 10**18, 0, 1 * 30, 1 * 30, 100]; ``` --- Preliminary report only: The auditors would like to confirm that `_startTime + 1 * 30 days` is the first time of the second-round release, is that correct?

LowInconsistency and Inadequacy in Transfer RestrictFixed

In the `_transfer()` function, the following comment suggests that the contract deployer is restricted to transferring tokens only once and exclusively to wallets within organizations. However, the actual implementation of the code enforces these restrictions on the `_owner` instead of the deployer. Furthermore, the existing `require` check within the code does not effectively enforce the one-time transfer limitation for the `_owner`. ```solidity=524 //部署合约的地址只能转给机构下的钱包,且只能转一次 if (from == _owner) { require( walletRecords[to].index != 0 && walletRecords[to].lastRelease == 0, "can not tx" ); } ```

LowInconsistency In The Logic of Setting Start TimeFixed

The line 369 in the `setStartTime()` function requires `startTime >= block.timestamp`. However, the line 463 in the `_releaseToken()` requires `_startTime` to be larger than `nowTime` (block.timestamp) when `setStartTime()` is called. ```solidity=369 require(startTime >= block.timestamp, "time error"); ``` ```solidity=463 require(nowTime < _startTime, "not initial time"); ```

Show 2 more
LowPotential Unintended Behavior During the Period BFixed

The `_lockBalanceNum()` function encounters a potential oversight when handling the scenario where `walletRecorde.lastRelease != 0`. Specifically, the function lacks the logic to address the period between the first-time release of tokens and the subsequent release. This absence of consideration for the period may lead to unintended behaviors in token lock calculations.

LowRedundant Require Check in `_transfer()` FunctionFixed

In the `_transfer()` function, the require check at line 540 is redundant since it is placed after the require check at line 536. In the `_transfer()` function of the contract, two `require` statements (at lines 536 and 540) are designed to ensure the validity of a token transfer. Given that the first check already encompasses the validation performed by the second, the latter becomes redundant and does not contribute any additional security or functional checks to the contract's operation. ```solidity=536 require(fromBalance - lockBalanceNumValue >= amount, "not enough"); ``` ```solidity=540 require( fromBalance >= amount, "ERC20: transfer amount exceeds balance" ); ```

Contracts in scope

No deployed address is recorded for this audit.

The report names a repository or files. Open the report to see its scope.

Repository and files the report names (5)

  • contracts/TMT.sol
  • contracts/ERC20/ERC20.sol
  • contracts/Optimized_DistributionERC20.sol
  • contracts/ERC20/Optimized_ERC20.sol
  • contracts/DistributionERC20.sol

Part of Tometa72 DAO’s security record

Tometa72 DAO
Audits1 audit by 1 firmLast audit Feb 2024, by CertiK.
Critical findingsNo open critical findingsIn that report, 1 critical finding was reported. It is marked fixed by the firm that reported it.
Open Tometa72 DAO’s security record

Security firm

CertiK

1,044 projects reviewed · 1,375 reports · latest May 2025

See CertiK’s audits

Something 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