1MDC token - audit

CertiK1 address on BNB Chain

CertiK reviewed 1MDC Coin (1MDC token - audit) on 20 Jun 2024: 18 findings, 0 critical; 6 acknowledged, 12 open.

No open critical findings
Open the reportOpen 1MDC Coin’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings18

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

SeverityOpenAcknowledgedFixed
Critical000
High030
Medium030
Low1200
LowDiscussion on the Usage of `tx.origin`Open

EIP3074 introduces two EVM instructions AUTH and AUTHCALL. The AUTH instruction sets a context variable, 'authorized', based on an ECDSA signature, while AUTHCALL enables sending a call as authorized. This pivotal enhancement allows smart contracts to delegate control of an EOA, enabling transactions to be sent within the context of said EOA, effectively bypassing certain checks. Moreover, the usage of `tx.origin` is heavily discouraged due to potential phishing attempts. For contracts, `tx.origin` lacks transparency. In a call chain scenario such as A->B->C->D, within contract D, `msg.sender` will be C, while `tx.origin` will trace back to A. If the origin is crucial within D, a method of propagation is suggested: each contract (B, C, D) could take an extra parameter to carry the origin. This way, A would pass its address (this) to B, B to C, and C to D. However, relying solely on `tx.origin` for authorization is susceptible to abuse by malicious contracts, especially if a legitimate user interacts with the malicious one. Consequently, it is not recommended to employ tx.origin for authorization in Solidity, as emphasized in the Solidity documentation. Refer to: [Solidity Documentation - Security Considerations](https://docs.soliditylang.org/en/v0.8.18/security-considerations.html#tx-origin)

LowMissing Zero Address ValidationOpen

Addresses are not validated before assignment or external calls, potentially allowing the use of zero addresses and leading to unexpected behavior or vulnerabilities. For example, transferring tokens to a zero address can result in a permanent loss of those tokens. ```solidity=232 _owner = msgSender; ``` - `msgSender` is not zero-checked before being used. --- ```solidity=1016 _tokenOwner = tokenOwner; ``` - `tokenOwner` is not zero-checked before being used.

LowNon-refundable Purchase if less than minimum threOpen

In the contract `Token`, the `receive()` function handles the purchase of the `1MDC` token. If the `startTime` is reached, and if the `msg.value` is greater than or equal to `10**10`, then the contract will transfer the `1MDC` token to the `msg.sender` and also send the native coin to to the inviters. Finally the function will send the leftover native coins to the `_bnbReciverAddress`. However, if the minimum amount of purchase is not satisfied, i.e. the `msg.value` is less than `10**10`, the transaction will not be reverted. The full amount of the `msg.value` will be redirected to the `_bnbReciverAddress`. ```sol=1032 receive() external payable { if(startTime > block.timestamp){ if(msg.value >= 10**10){ uint256 sendAmount = getUserMintAmount(msg.value); if(sendAmount > 0){ super._transfer(_tokenOwner, msg.sender, sendAmount); _takeInviterFee(msg.sender, msg.value); } } _bnbReciverAddress.transfer(address(this).balance); } } ``` In addition, in the `getUserMintAmount()`, we noticed that the price of `1MDC : BNB` is hardcoded as `1 BNB = 1 * 10 ** 28 / 10 ** 18 1MDC => 1 BNB = 10**10 1MDC`, we would like to learn if there are any other mechanisms to maintain the price.

LowRedundant conditions in `if` statement of the `_tOpen

In the `_transfer()` function of the `Token` contract, there is an `if` statement to control whether to call the `swapAndLiquify()` function. There are two redundant statements in the `if` statement: `!swapping` and `swapAndLiquifyEnabled`. Both the `swapping` and `swapAndLiquifyEnabled` variables are state variables, where `swapping` is never set and by default initialized to `false` by Solidity, and `swapAndLiquifyEnabled` is initialized to `true`. These two variables are not set or used in other functions and the current value of `!swapping && swapAndLiquifyEnabled` is always true. ```sol=1108 if ( balanceOf(address(this)) > super.balanceOf(uniswapV2Pair).div(500) ) { if ( !swapping && _tokenOwner != from && _tokenOwner != to && to == uniswapV2Pair && swapAndLiquifyEnabled ) { swapAndLiquify(); } ```

LowState Variable Should Be Declared ConstantOpen

State variables that never change should be declared as `constant` to save gas. ```solidity=987 bool private swapping; ``` - `swapping` should be declared `constant`. --- ```solidity=989 address _cakeRouter = address(0x10ED43C718714eb63d5aA57B78B54704E256024E);//router ``` - `_cakeRouter` should be declared `constant`. --- ```solidity=990 address _baseToken = address(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c);//wbnb ``` - `_baseToken` should be declared `constant`. --- ```solidity=991 IERC20 public USDT = IERC20(0x55d398326f99059fF775485246999027B3197955); ``` - `USDT` should be declared `constant`. --- ```solidity=993 address _destroyAddress = address(0x000000000000000000000000000000000000dEaD); ``` - `_destroyAddress` should be declared `constant`. --- ```solidity=994 address payable _bnbReciverAddress = payable(address(0xB408CD6D80dC8cabb0f0cEF0226A4FdE11704Fad)); ``` - `_bnbReciverAddress` should be declared `constant`. --- ```solidity=995 address defaultAddress = address(0xB408CD6D80dC8cabb0f0cEF0226A4FdE11704Fad); ``` - `defaultAddress` should be declared `constant`. --- ```solidity=1000 bool public swapAndLiquifyEnabled = true; ``` - `swapAndLiquifyEnabled` should be declared `constant`. --- ```solidity=1003 uint256 daySecond = 3600; ``` - `daySecond` should be declared `constant`. --- ```solidity=1029 uint256 public baseBnbAmount = 10**18; ``` - `baseBnbAmount` should be declared `constant`. --- ```solidity=1030 uint256 public oneBaseAmount = 10**28; ``` - `oneBaseAmount` should be declared `constant`.

LowThird-Party Dependency UsageOpen

The contract is serving as the underlying entity to interact with one or more third party protocols. The scope of the audit treats third party entities as black boxes and assumes their functional correctness. However, in the real world, third parties can be compromised and this may lead to lost or stolen assets. In addition, upgrades of third parties can possibly create severe impacts, such as increasing fees of third parties, migrating to new LP pools, etc. --- ```solidity=988 address public uniswapV2Pair; address _cakeRouter = address(0x10ED43C718714eb63d5aA57B78B54704E256024E); //router address _baseToken = address(0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c); //wbnb IERC20 public USDT = IERC20(0x55d398326f99059fF775485246999027B3197955); ``` - The contract `Token` interacts with third party contract with `IUniswapV2Pair` interface via `uniswapV2Pair`. - The contract `Token` interacts with third party contract with `IERC20` interface via `USDT` and `_baseToken`. --- ```solidity=1010 IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(_cakeRouter); address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()) ``` - The contract `Token` interacts with third party contract with `IUniswapV2Router02` interface via `uniswapV2Router`.

LowUnchecked ERC-20 `transfer()`/`transferFrom()` CaOpen

The return values of the `transfer()` and `transferFrom()` calls in the smart contract are not checked. Some ERC-20 tokens' transfer functions return no values, while others return a bool value, they should be handled with care. If a function returns `false` instead of reverting upon failure, an unchecked failed transfer could be mistakenly considered successful in the contract. ```solidity=1305 USDT.transfer(user,buyRewardTokenAmount); ``` --- ```solidity=1315 USDT.transfer(user,buyRewardTokenAmount); ```

LowUnnecessary Use of SafeMathOpen

The `SafeMath` library is used unnecessarily. With Solidity compiler versions 0.8.0 or newer, arithmetic operations will automatically revert in case of integer overflow or underflow. ```solidity=275 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `ERC20` contract. ```solidity=419 _approve( sender, _msgSender(), _allowances[sender][_msgSender()].sub( amount, "ERC20: transfer amount exceeds allowance" ) ); ``` - `SafeMath.sub` is called in `transferFrom` function of `ERC20` contract. *Note: Only a sample of 2 `SafeMath` library usage in this contract (out of 13) are shown above.* --- ```solidity=620 library SafeMath { ``` - An implementation of `SafeMath` library is found. --- ```solidity=275 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `ERC20` contract. ```solidity=1046 return bnbAmount.mul(oneBaseAmount).div(baseBnbAmount); ``` - `SafeMath.mul` is called in `getUserMintAmount` function of `Token` contract. *Note: Only a sample of 2 `SafeMath` library usage in this contract (out of 34) are shown above.*

LowUnused Return ValueOpen

The smart contract does not check or store the return value of an external call in a local or state variable, which may introduce vulnerabilities due to the unhandled outcome. ```solidity=1198 (uint r0,,) = IUniswapV2Pair(address(uniswapV2Pair)).getReserves(); ``` --- ```solidity=1211 (uint reserves0,,) = IUniswapV2Pair(address(uniswapV2Pair)).getReserves(); ``` --- ```solidity=1252 uniswapV2Router.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, 0, _destroyAddress, block.timestamp ); ```

LowUse case of State variable `ktNum`Open

In the `Token` contract, there is a state variable `ktNum`. It is initialized to be `173` and used in the function `_transfer2otherAddress()`. Our current understanding is that this value is to generate `_receiveD` addresses to transfer small amounts of tokens. ```sol=1223 uint160 ktNum = 173; uint160 constant MAXADD = ~uint160(0); function _transfer2otherAddress( uint256 amount ) private { address _receiveD; for (uint256 i = 0; i < 3; i++) { _receiveD = address(MAXADD/ktNum); ktNum = ktNum+1; super._transfer(address(this), _receiveD, amount.div(i+10)); } } ```

Show 2 more
LowUse Cases of Unused FunctionsOpen

In the `Token` contract, there are functions that are implemented but never used: * `_isAddLiquidityV2()` * `_isDelLiquidityV2()` * `_transfer2otherAddress()` These functions have visibilities of either `internal` or `private`, which means if the functions are not used in the contract, the functions are not callable by external users or contracts either.

LowVariable That Could Be Declared As ImmutableOpen

The linked variables assigned in the constructor can be declared as `immutable`. Immutable state variables can be assigned during contract creation but will remain constant throughout the lifetime of a deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper than reading from regular state variables since they will not be stored in storage. ```sol=984 IUniswapV2Router02 public uniswapV2Router; ``` ```sol=988 address public uniswapV2Pair; ```

Contracts in scope1

AddressChainSource code
0xf43c9b40c9361b301019c98fb535affb3ec6c673Chain: BNB ChainSource code: Verified source

Part of 1MDC Coin’s security record

1MDC Coin
Audits1 audit by 1 firmLast audit Jun 2024, by CertiK.
Critical findingsNo open critical findingsIn 1 report.
Open 1MDC Coin’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