Metaverse User DAO - Addendum

CertiKFiles named in the report

CertiK reviewed Metaverse User DAO (Metaverse User DAO - Addendum) on 21 Apr 2023: 11 findings, 0 critical; none marked fixed.

No open critical findings
Open the reportOpen Metaverse User DAO’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings11

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

SeverityOpenAcknowledgedFixed
Critical000
High100
Medium100
Low900
HighCentralization Related RisksOpen

In the contract `MudAngelRoundReleaseBank` the role `admin` has authority over the functions shown below: * icoDeposits(): deposit `MUD` tokens to investor. * icoFinalised(): mark the `ICO` finished flag, stop `icoDeposit`. Any compromise to the `admin` account may allow the hacker to take advantage of this authority and do the following: * Deposit `MUD` tokens to themselves or block `ICO`. In the contract `MudTeamReleaseBank` the role `admin` has authority over the functions shown below: * teamMemberDeposit(): deposit `MUD` tokens to team members, lock the team's `MUD` tokens to the contract and start to release after 365 days in daily release rate. * icoFinalised(): mark the `ICO` finished flag, stop `icoDeposit`. Any compromise to the `admin` account may allow the hacker to take advantage of this authority and do the following: * Deposit `MUD` tokens to themselves or block `ICO`. In the contract `MudMiningPool` the role `admin` has authority over the functions shown below: * icoDeposit(): deposit `MUD` tokens to the pool. Any compromise to the `admin` account may allow the hacker to take advantage of this authority and do the following: * Refuse deposit `MUD` tokens. In the contract `MudMiningPool` the role `miningDappAddress` has authority over the functions shown below: * miningStart(): start mining process. * miningSettlement(): settle mining tokens. Any compromise to the `miningDappAddress` may allow the hacker to take advantage of this authority and do the following: * Start mining process at any time as they want. * Settle tokens to themselves.

MediumNot Update `dailyMiningLimit` for Other BatchesOpen

In the function `miningSettlement()` of contract `MudMiningPool`, the `dailyMiningLimit` is just checked whether it should be halved only in the last settlement batch. If current settlement is divided into 5 batches (1,2,3,4,0), and it has been 4 years since the last `lastHalvingTime`, according to the logic, only in the last batch (batchNumber = 0) the `dailyMiningLimit` will be halved. In this case, it should be halved starting from batch #1. Besides, the half time could happen in any batch during a settlement.

LowCostly Operation Inside LoopOpen

Accessing storage variables in a loop can be costly in terms of gas consumption. ```solidity=64 _icoDepositTotal = _icoDepositTotal + balanceArray[i]; ``` --- ```solidity=65 _icoDepositTotal = _icoDepositTotal + balanceArray[i]; ``` --- ```solidity=116 _totalSettlementAmount = _totalSettlementAmount + balanceArray[i]; ```

LowDivide Before MultiplyOpen

Performing integer division before multiplication truncates the low bits, losing the precision of calculation. ```solidity=102 dailyMiningLimit = dailyMiningLimit / 2; ``` ```solidity=110 uint256 settlementLimit = dailyMiningLimit * settlementPeriod; ```

LowLack of ValidationOpen

According to the `require` conditions in the functions `checkBalance()` and `withdraw()`, `miningDappAddress` is also excluded from this ico. Therefore, the mining address should be checked for `miningDappAddress` in the settlement loop. ```solidity for (uint i = 0; i < addressArray.length; i++) { require(addressArray[i] != admin && addressArray[i] != address(0), "invalid address"); require(balanceArray[i] > 0); _totalSettlementAmount = _totalSettlementAmount + balanceArray[i]; require(_totalSettlementAmount <= settlementLimit, "TotalAmount out of settlement limit!"); // > daily limit, trasaction failed. _minedToken[addressArray[i]] = _minedToken[addressArray[i]] + balanceArray[i]; } ```

LowMissing Emit EventsOpen

There should always be events emitted in the sensitive functions that are controlled by centralization roles.

LowMissing Error MessagesOpen

The **require** can be used to check for conditions and throw an exception if the condition is not met. It is better to provide a string message containing details about the error that will be passed back to the caller.

LowMissing Input ValidationOpen

In the function `miningSettlement()` of contract `MudMiningPool`, the `batchNumber` is not validated. In the same settlement, `batchNumber` should be starting from 1 and increasing by 1 in subsequent batches, then ending at zero. But there is no logic to check whether the input `batchNumber` is passed correctly, for example, duplicate `batchNumber` for the same settlement in different batches.

LowRedundant `require` StatementsOpen

In the contract `MudAngelRoundReleaseBank`, investors or admin are required to call function `checkBalance()` to check their locked `MUD` token amount after the `lastTIme`. ```solidity=88 require(block.timestamp > bank[addressToCheck].lastTime, "now time should > lastTime"); ``` If admin doesn't deposit MUD for `addressToCheck`, `bank[addressToCheck].lastTime` is equal to 0; once deposited, `bank[addressToCheck].lastTime` is just the time in the past, the condition in `require` statement can be true. The only timestamp it reverts is just the calling time is equal to depositing time, but this happens rarely. Even though it does, the remaining code can cover this and return `(0,0)`.

LowState Variable Should Be Declared ConstantOpen

State variables that never change should be declared as `constant` to save gas. --- ```solidity=22 uint256 settlementPeriod = 7; //7 days ``` - `settlementPeriod` should be declared `constant`.

Show 1 more
LowUnnecessary Self Approve and BurnOpen

In the function `miningSettlement` of contract `MudMiningPool`, it will call below two functions of `MUD` token. Here the `msg.sender` of both calls are just the contract itself equal to `address(this)`, it first increases allowance of `MUD` token for itself and then burns `MUD` token out if itself. ```solidity=138 require(token.increaseAllowance(address(this), amountToBurn), "increaseAllowance failed!"); token.burnFrom(address(this), amountToBurn); ```

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 (4)

  • .workspaces/code-sample/UtilityFunctions.sol
  • .workspaces/code-sample/icoReleaseAngelRound.sol
  • .workspaces/code-sample/miningPool.sol
  • .workspaces/code-sample/teamRelease.sol

Part of Metaverse User DAO’s security record

Metaverse User DAO
Audits4 audits by 1 firmLast audit Sep 2023, by CertiK.
Critical findingsNo open critical findingsAcross the 4 reports, 2 critical findings were reported. Each is marked fixed by the firm that reported it.
Open Metaverse User DAO’s security record

Security firm

CertiK

1,045 projects reviewed · 1,376 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