Livegreencoin

CertiK1 address on BNB Chain

CertiK reviewed LiveGreen Coin (Livegreencoin) on 28 May 2023: 17 findings, 1 critical; 1 acknowledged, 16 open.

1 open critical finding
Open the reportOpen LiveGreen Coin’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings17

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

SeverityOpenAcknowledgedFixed
Critical100
High010
Medium000
Low1500
CriticalLack Of Access ControlOpen

The function `MAPSet()` and `MAPRemove()` can be called by anyone as they have no access restriction. Anyone can call the `MAPSet()` function to become a token holder or call the `MAPRemove()` function to remove other holders from the map. ```solidity function MAPSet(address key, uint val) public { if (tokenHoldersMap.inserted[key]) { tokenHoldersMap.values[key] = val; } else { tokenHoldersMap.inserted[key] = true; tokenHoldersMap.values[key] = val; tokenHoldersMap.indexOf[key] = tokenHoldersMap.keys.length; tokenHoldersMap.keys.push(key); } } function MAPRemove(address key) public { if (!tokenHoldersMap.inserted[key]) { return; } delete tokenHoldersMap.inserted[key]; delete tokenHoldersMap.values[key]; uint index = tokenHoldersMap.indexOf[key]; uint lastIndex = tokenHoldersMap.keys.length - 1; address lastKey = tokenHoldersMap.keys[lastIndex]; tokenHoldersMap.indexOf[lastKey] = index; delete tokenHoldersMap.indexOf[key]; tokenHoldersMap.keys[index] = lastKey; tokenHoldersMap.keys.pop(); } ```

LowAddresses Meant To Be Excluded From Dividends MayOpen

The constructor of the contract `CoinToken` excludes the contract's owner, the dead wallet, the UniswapV2 pair, and the UniswapV2 router from dividends. ```solidity _setAutomatedMarketMakerPair(_uniswapV2Pair, true); ... function _setAutomatedMarketMakerPair(address pair, bool value) private { require(automatedMarketMakerPairs[pair] != value, "Automated market maker pair is already set to that value"); automatedMarketMakerPairs[pair] = value; if(value) { dividendTracker.excludeFromDividends(pair); } emit SetAutomatedMarketMakerPair(pair, value); } ``` ```solidity=1330 dividendTracker.excludeFromDividends(owner()); dividendTracker.excludeFromDividends(deadWallet); dividendTracker.excludeFromDividends(address(_uniswapV2Router)); ``` However, when changing any of the above key addresses, the new address is not removed from dividends. Changing the owner: ```solidity=37 function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } ``` Changing the dead wallet: ```solidity=1496 function setDeadWallet(address addr) public onlyOwner { deadWallet = addr; } ``` Changing the UniswapV2 router and pair: ```solidity=1355 function updateUniswapV2Router(address newAddress) public onlyOwner { require(newAddress != address(uniswapV2Router), "The router already has that address"); emit UpdateUniswapV2Router(newAddress, address(uniswapV2Router)); uniswapV2Router = IUniswapV2Router02(newAddress); address _uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory()) .createPair(address(this), uniswapV2Router.WETH()); uniswapV2Pair = _uniswapV2Pair; } ```

LowContract gains non-withdrawable ETH via the `swapOpen

The `swapAndLiquify` function converts part of the `contractTokenBalance` `CoinToken` to ETH. The other part of `CoinToken` and part of the converted ETH are deposited into the `CoinToken-ETH` pool on Uniswap as liquidity. For every `swapAndLiquify` function call, a small amount of ETH is left over in the contract. This is because the price of `CoinToken` drops after swapping the first part of `CoinToken` into ETH, and the other part of `CoinToken` require less than the converted ETH to be paired with it when adding liquidity. The contract doesn't appear to provide a way to withdraw those ETH, and they will be locked in the contract forever.

LowImproper Use of Try/Catch When Setting BalancesOpen

The `try / catch` keywords are used to handle failed external calls and are used in the `_transfer()` function when setting balances of the sender and recipient. ```solidity=1589 try dividendTracker.setBalance(payable(from), balanceOf(from)) {} catch {} try dividendTracker.setBalance(payable(to), balanceOf(to)) {} catch {} ``` If one of the above calls failed, such as due to an overflow error or casting error, the transaction will not revert. This may be an issue as tokens are still transferred between `from` and `to`.

LowIncorrect `swapTokensAtAmount` ValueOpen

The variable `swapTokensAtAmount` is used to determine the threshold for when to swap fees for rewards, liquidity, and dividends. The documentation states that this threshold is 0.002% of the total supply. ```solidity=1309 swapTokensAtAmount = totalSupply.mul(2).div(10**6); // 0.002% ``` However, the implementation actually uses 0.0002%.

LowMissing Emit EventsOpen

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

LowMissing Zero Address ValidationOpen

Addresses should be checked before assignment or external call to make sure they are not zero addresses. ```solidity=817 REWARD_TOKEN = _rewardTokenAddress; ``` - `_rewardTokenAddress` is not zero-checked before being used. --- ```solidity=1323 uniswapV2Pair = _uniswapV2Pair; ``` - `_uniswapV2Pair` is not zero-checked before being used. --- ```solidity=1357 uniswapV2Pair = _uniswapV2Pair; ``` - `_uniswapV2Pair` is not zero-checked before being used. --- ```solidity=1376 _marketingWalletAddress = wallet; ``` - `wallet` is not zero-checked before being used. --- ```solidity=1497 deadWallet = addr; ``` - `addr` is not zero-checked before being used.

LowPotential Issue in Fee ChargingOpen

The function `_transfer` will charge a transfer fee. The issue is that when both `from` and `to` accounts are included in `automatedMarketMakerPairs`, the `AmountLiquidityFee`, `AmountTokenRewardsFee`, and `AmountMarketingFee` will be accumulated twice: ```solidity if(automatedMarketMakerPairs[from]){ LFee = amount.mul(buyLiquidityFee).div(100); AmountLiquidityFee += LFee; RFee = amount.mul(buyTokenRewardsFee).div(100); AmountTokenRewardsFee += RFee; MFee = amount.mul(buyMarketingFee).div(100); AmountMarketingFee += MFee; DFee = amount.mul(buyDeadFee).div(100); fees = LFee.add(RFee).add(MFee).add(DFee); } if(automatedMarketMakerPairs[to]){ LFee = amount.mul(sellLiquidityFee).div(100); AmountLiquidityFee += LFee; RFee = amount.mul(sellTokenRewardsFee).div(100); AmountTokenRewardsFee += RFee; MFee = amount.mul(sellMarketingFee).div(100); AmountMarketingFee += MFee; DFee = amount.mul(sellDeadFee).div(100); fees = LFee.add(RFee).add(MFee).add(DFee); } ``` However, the user will only have the fees deducted once: ```solidity if(automatedMarketMakerPairs[from]){ .... fees = LFee.add(RFee).add(MFee).add(DFee); } if(automatedMarketMakerPairs[to]){ .... fees = LFee.add(RFee).add(MFee).add(DFee); } amount = amount.sub(fees); ... ``` This will result in an inconsistency between the actual fee charged and the calculated fee and when the fee is swapped it may fail because the actual fee maybe insufficient.

LowRaising Minimum Token Balance For Dividends DoesOpen

For a user to receive dividends, their token balance should exceed the `minimumTokenBalanceForDividends` variable. This variable can be changed via the `setMinimumTokenBalanceForDividends()` function. ```solidity=980 function setMinimumTokenBalanceForDividends(uint256 val) external onlyOwner { minimumTokenBalanceForDividends = val; } ``` However, when `minimumTokenBalanceForDividends` is changed, the users that can receive dividends is unchanged. This means that if `minimumTokenBalanceForDividends` is increased, users whose balance is below the new `minimumTokenBalanceForDividends` but above the old `minimumTokenBalanceForDividends` can still receive dividends.

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

The return value of the transfer()/transferFrom() call is not checked. ```solidity=1608 IERC20(rewardToken).transfer(_marketingWalletAddress, newBalance); ```

Show 6 more
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=81 library SafeMath { ``` - An implementation of `SafeMath` library is found. --- ```solidity=272 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `ERC20` contract. ```solidity=394 _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); ``` - `SafeMath.sub` is called in `transferFrom` function of `ERC20` contract. --- ```solidity=272 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `ERC20` contract. ```solidity=825 magnifiedDividendPerShare = magnifiedDividendPerShare.add( (amount).mul(magnitude) / totalSupply() ); ``` - `SafeMath.mul` is called in `distributeCAKEDividends` function of `DividendPayingToken` contract. --- ```solidity=272 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `ERC20` contract. ```solidity=1034 uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length > lastProcessedIndex ? tokenHoldersMap.keys.length.sub(lastProcessedIndex) : 0; ``` - `SafeMath.sub` is called in `getAccount` function of `TokenDividendTracker` contract. --- ```solidity=272 using SafeMath for uint256; ``` - `SafeMath` library is used for `uint256` type in `ERC20` contract. ```solidity=1305 require(buyTokenRewardsFee.add(buyLiquidityFee).add(buyMarketingFee).add(buyDeadFee) <= 25, "Total buy fee is over 25%"); ``` - `SafeMath.add` is called in `constructor` function of `CoinToken` contract.

LowUnsafe Integer CastOpen

```solidity=1031 iterationsUntilProcessed = index.sub(int256(lastProcessedIndex)); ``` - The type conversion `int256(lastProcessedIndex)` from type uint256 to type int256 may flip the value's sign. --- ```solidity=1039 iterationsUntilProcessed = index.add(int256(processesUntilEndOfArray)); ``` - The type conversion `int256(processesUntilEndOfArray)` from type uint256 to type int256 may flip the value's sign. --- ```solidity=1168 return int(tokenHoldersMap.indexOf[key]); ``` - The type conversion `int256(tokenHoldersMap.indexOf[key])` from type uint256 to type int256 may flip the value's sign.

LowUnused Return ValueOpen

The return value of an external call is not stored in a local or state variable. ```solidity=1471 dividendTracker.processAccount(payable(msg.sender), false); ``` --- ```solidity=1595 try dividendTracker.process(gas) returns (uint256 iterations, uint256 claims, uint256 lastProcessedIndex) { emit ProcessedDividendTracker(iterations, claims, lastProcessedIndex, true, gas, tx.origin); } catch { } ``` --- ```solidity=1670 uniswapV2Router.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, // slippage is unavoidable 0, // slippage is unavoidable _node, block.timestamp ); ```

LowUpdating `_uniswapV2Pair` Without Checking ExisteOpen

In function `updateUniswapV2Router()`, new pair is created without checking existence. If the new pair is already created, `IUniswapV2Factory` will revert the transaction. As a result, the new router will never be set successfully.

LowUsage of `transfer`/`send` for sending EtherOpen

It is not recommended to use Solidity's `transfer()` and `send()` functions for transferring Ether, since some contracts may not be able to receive the funds. Those functions forward only a fixed amount of gas (2300 specifically) and the receiving contracts may run out of gas before finishing the transfer. Also, EVM instructions' gas costs may increase in the future. Thus, some contracts that can receive now may stop working in the future due to the gas limitation. ```solidity=1341 payable(_node).transfer(msg.value); ``` - `CoinToken.constructor` uses `transfer()`.

LowVariables 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.

Contracts in scope1

AddressChainSource code
0x3496212ec43cc49f5151ec4405efd4975e036f89Chain: BNB ChainSource code: Verified source

Part of LiveGreen Coin’s security record

LiveGreen Coin
Audits1 audit by 1 firmLast audit May 2023, by CertiK.
Critical findings1 open critical findingReported in “Livegreencoin” by CertiK, May 2023. Not marked fixed in that report.
Open LiveGreen 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