CertiK reviewed Magic Shoes on 28 Jun 2023: 15 findings, 0 critical; 9 marked fixed, 3 acknowledged, 3 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 | 2 |
| Medium | 0 | 1 | 4 |
| Low | 3 | 0 | 3 |
The calculation of `timeDiff` should not include `lockIn` in the else statement in L305: ```solidity if (poolLastClaimTime[poolId] == 0) { timeDiff = block.timestamp - (START_TIME + lockIn); } else { timeDiff = block.timestamp - (poolLastClaimTime[poolId] + lockIn);// CertiK: should not include lockIn here } ``` This will lead to multiple lock up in each claim.
The functions `claimUnvestedOperationalPoolTokens()` and `claimUnvestedTeamTokens()` share the same `poolId`. The state variables `poolClaimedAmount` and `poolLastClaimTime` will be messed up. In the below example, the later called function cannot claim a correct number of tokens because of sharing the `poolLastClaimTime`.
All tokens received from the `INVESTOR_POOL` will be treated as investments. The investment tokens cannot be transferred in 26 weeks. Even if 26 weeks passed, the `INVESTOR_POOL` transferred tokens to the investor again, the `investedAt` will be overridden, which means the token locks will be reset.
The functions `addSigner()/removeSigner()` are `onlyOwner` functions, which means the owner can replace all signers by the following steps: 1. add 3 signers and publish their addresses, for example, signer1,signer2,signer3 2. remove signer1 and add signer4 3. remove signer2 and add signer5 4. remove signer3 and add signer6
If the current time does not exceed 26 weeks after the `investedAt` time, the token transfer will fail due to underflow.
In the function `_beforeTokenTransfer()`, if `weeksElapsed` is greater than 52 weeks, all tokens will be released. Else, a check on the released amount will be performed. However, if the amount is greater than `balanceOf(from) - investment[from]`, the below validation will be bypassed. This means any investments after 26 weeks can be released without vesting schedule. ```solidity if (amount <= balanceOf(from) - investment[from]) { require( block.timestamp >= investedAt[from] + 26 weeks, "MCT: Lock-in Period" ); require(weeksElapsed > 0, "MCT: Vesting Period"); uint256 weeklyVesting = investment[from] / 52 weeks; uint256 amountVested = weeklyVesting * weeksElapsed; require( amount <= amountVested, "MCT: Transfer exceeds Vest" ); } ```
Literals with many digits are difficult to read and review. ```solidity=10 uint256 public constant MAX_SUPPLY = 6000000000 * 10 ** 18; ``` --- ```solidity=16 uint256 public constant MINING_POOL_ALLOCATION = 3600000000 * 10 ** 18; ``` --- ```solidity=17 uint256 public constant AIRDROP_ALLOCATION = 600000000 * 10 ** 18; ``` --- ```solidity=18 uint256 public constant RESERVE_POOL_ALLOCATION = 720000000 * 10 ** 18; ``` --- ```solidity=19 uint256 public constant OPERATIONAL_POOL_ALLOCATION = 420000000 * 10 ** 18; ``` --- ```solidity=20 uint256 public constant TEAM_ALLOCATION = 420000000 * 10 ** 18; ``` --- ```solidity=21 uint256 public constant INVESTOR_ALLOCATION = 180000000 * 10 ** 18; ```
Some state variables are not used in the codebase. This can lead to incomplete functionality or potential vulnerabilities if these variables are expected to be utilized. Variable `signers` in `MCT` is never used in `MCT`. ```solidity=65 address[] private signers; ``` ```solidity=11 contract MCT is ERC20, Ownable { ```
When a signer is removed, the previous vote is not removed. This could lead to the proposal being executed without sufficient vote.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (1)
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