CertiK reviewed Catcoincrypto (CatCoin V2) on 13 May 2022: 13 findings, 0 critical; none marked fixed.
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 | 4 | 0 | 0 |
| Medium | 0 | 0 | 0 |
| Low | 9 | 0 | 0 |
Over time, these accounts `withdrawcontract` and `_devwallet` will accumulate a significant amount of BNB. ```solidity=579 payable(withdrawcontract).transfer(amountBNB); ``` ```solidity=800 if (marketingAmt > 0) { payable(withdrawcontract).transfer(marketingAmt); } if (devAmt > 0) { payable(_devwallet).transfer(devAmt); } ```
In the contract `Catcoin` the role `_devwallet` has authority over the functions shown in the diagram below. Any compromise to the `_devwallet` account may allow the hacker to take advantage of this authority.  In the contract `Catcoin` 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.  In the contract `Catcoin` the role `multisig`, which is a multi-signature contract, has authority over the functions shown in the diagram below. If the `multisig` contract is updated to an EOA account, any compromise to the `multisig` account may allow the hacker to take advantage of this authority.  In the contract `Ownable` 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. 
```solidity=833 uniswapV2Router.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, 0, withdrawcontract, block.timestamp ); ``` The `addLiquidity` function calls the `uniswapV2Router.addLiquidityETH` function with the `to` address specified as `withdrawcontract` for acquiring the generated LP tokens from the `Catcoin-BNB` pool. As a result, over time the `withdrawcontract` address will accumulate a significant portion of LP tokens. If the `withdrawcontract` is an EOA (Externally Owned Account), mishandling of its private key can have devastating consequences for the project as a whole.
All of the Catcoin tokens are sent to the contract deployer when deploying the contract. This could be a centralization risk as the deployer can distribute Catcoin tokens without obtaining the consensus of the community.
The variable `takeFee` indicates if the fee should be deducted when transferring tokens. But when `takeFee` is true and `sender` and `recipient` are also not equal to the `uniswapV2Pair`, the function `removeAllFee` will set all fee settings to zero. In line 864, after each call to the function `_tokenTransfer`, all fee settings will be set to zero when the function `removeAllFee` is called. ```solidity=844 if (takeFee) { removeAllFee(); if (sender == uniswapV2Pair) { setBuy(); } if (recipient == uniswapV2Pair) { setSell(); } } if (_isExcluded[sender] && !_isExcluded[recipient]) { _transferFromExcluded(sender, recipient, amount); } else if (!_isExcluded[sender] && _isExcluded[recipient]) { _transferToExcluded(sender, recipient, amount); } else if (_isExcluded[sender] && _isExcluded[recipient]) { _transferBothExcluded(sender, recipient, amount); } else { require(!_isExcluded[sender] && !_isExcluded[recipient]); _transferStandard(sender, recipient, amount); } removeAllFee(); ``` At the end of the `_tokenTransfer` function as shown below, why not restore the fees but still remove all fees? ```solidity=843 function _tokenTransfer(address sender, address recipient, uint256 amount, bool takeFee) private { if (takeFee) { removeAllFee(); ... } if (_isExcluded[sender] && !_isExcluded[recipient]) { _transferFromExcluded(sender, recipient, amount); } ... removeAllFee(); } ```
`public` functions that are never called by the contract could be declared as `external`. `external` functions are more efficient than `public` functions.
Lack of input validation when setting fees in the `setFees` function to ensure the below denominator to be greater than zero. ```solidity uint256 denominator = (buyFee.liquidity + sellFee.liquidity + buyFee.marketing + sellFee.marketing + buyFee.dev + sellFee.dev) * 2; ```
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.
Addresses should be checked before assignment or external call to make sure they are not zero addresses. File: Catcoin.sol (Line 386, Function `Catcoin.setMultisig`) ```solidity multisig = _multisig; ``` - `_multisig` is not zero-checked before being used. --- File: Catcoin.sol (Line 734, Function `Catcoin.openTrading`) ```solidity withdrawcontract = _withdrawcontract; ``` - `_withdrawcontract` is not zero-checked before being used.
After the contract gets fees from the previous transfer, the function `swapAndLiquify` will likely be called in the next transfer because `contractTokenBalance > 0` is true. This will result in too frequent swaps and the value of the transferred tokens may be lower than the gas cost.
The return values of function `addLiquidityETH` are not properly handled. ```solidity=833 uniswapV2Router.addLiquidityETH{value: ethAmount}( address(this), tokenAmount, 0, 0, withdrawcontract, block.timestamp ); ```
The contract is serving as the underlying entity to interact with third-party PancakeSwap protocols. The scope of the audit treats 3rd party entities as black boxes and assumes their functional correctness. However, in the real world, 3rd parties can be compromised and this may lead to lost or stolen assets. In addition, upgrades of 3rd parties can possibly create severe impacts, such as increasing fees of 3rd parties, migrating to new LP pools, etc.
The condition `unitBalance * 2 * (buyFee.dev + sellFee.dev) > address(this).balance` is useless, because the `marketingAmt` BNB has not been transferred. Therefore, the check should be done after the transfer to `withdrawcontract` address happened.
| Address | Chain | Source code |
|---|---|---|
| 0x2f0c…53a20x2f0c6e147974bfbf7da557b88643d74c324053a2 | Chain: BNB Chain | Source code: Verified source |
| 0x7288…c56e0x728829b74577831f47953bcdbc8dfca27141c56e | Chain: BNB Chain | Source code: Verified source |
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