Shrub token

CertiK1 address on Ethereum

CertiK reviewed Shrub (Shrub token) on 29 Nov 2024: 12 findings, 0 critical; 1 marked fixed, 10 acknowledged, 1 open.

No open critical findings
Open the reportOpen Shrub’s security record

Report hosted on skynet.certik.com.

Trustblock does not review code.

Findings12

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

SeverityOpenAcknowledgedFixed
Critical000
High101
Medium010
Low090
MediumInadequate Blacklisting Mechanism for TransfersAcknowledged

The function contains a flaw in its implementation where it is supposed to blacklist a particular address by marking it as true in a blacklist mapping. However, due to a logic error, the flag is incorrectly set to false, leading to the address not being blacklisted as intended when a disallowed transfer action is performed. ```solidity // anti bot logic if ( block.number <= (launchedAt + 0) && to != uniswapV2Pair && to != address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D) ) { @> _blacklist[to] = false; } ```

LowCall Limit Of `enableTrading()`Acknowledged

The `enableTrading()` function is designed to be called by the owner to activate trading. However, this function can be invoked multiple times, with each invocation updating the `launchedAt` variable to the current `block.number`. This behavior may interfere with the proper functioning of the blacklist mechanism. ```solidity // once enabled, can never be turned off function enableTrading() external onlyOwner { tradingActive = true; swapEnabled = true; launchedAt = block.number; } ```

LowConfirmation Of the Swap FunctionalityAcknowledged

The deployed token contract includes a mechanism to swap tokens for ETH when specific conditions are satisfied. However, with fees set to 0 and ownership renounced, the swap operation is blocked by the following condition in the `swapBack()` function: ```solidity if (contractBalance == 0 || totalTokensToSwap == 0) { return; } ``` As a result, the contract currently holds approximately 7,823,630 tokens that cannot be swapped for ETH, leaving the tokens effectively stuck. Furthermore, approximately 4.464 ETH is also locked within the token contract.

LowIncorrect Token Balance Management in `swapBack()Acknowledged

The `swapBack()` function has an issue with token balance management, which may lead to incorrect calculations during swap operations. Specifically, not all tokens are transferred, leaving `liquidityTokens` in the contract. Despite this, the internal counters `tokensForLiquidity`, `tokensForMarketing`, and `tokensForDev` are reset to zero, without accounting for the remaining `liquidityTokens`. This premature reset may result in incorrect token accounting if fees are recalibrated immediately afterward. Furthermore, the contract lacks a mechanism to add liquidity, even though `liquidityTokens` are calculated and exist within the function. This oversight indicates a missing implementation step for adding liquidity to the liquidity pool.

LowLow-level Call UsageAcknowledged

The smart contract contains low-level calls such as `call()`. Since these calls bypass some of the automatic checks that Solidity provides, like function type checks, they can introduce vulnerabilities, logic errors, or unexpected behavior. ```solidity=1540 (success, ) = address(devWallet).call{value: ethForDev}(""); ``` ```solidity=1542 (success, ) = address(marketingWallet).call{ value: address(this).balance }(""); ```

LowMiscalculation of Max HoldingAcknowledged

The transaction may be charged fees, so the max holding of the receiver should be the sum of the held tokens and the amount received from the transfer. The fees should not be included in the max holding. ```solidity=1421 require( amount + balanceOf(to) <= maxWallet, "Max wallet exceeded" ); ``` - Max holding is checked. ```solidity=1486 amount -= fees; ``` - Receiving amount is adjusted. ```solidity=483 _balances[recipient] = _balances[recipient].add(amount); ``` - Balance is increased by the adjusted amount.

LowMissing Emit EventsAcknowledged

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

LowMissing Zero Address ValidationAcknowledged

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=1341 devWallet = newWallet; ``` - `newWallet` is not zero-checked before being used. ```solidity=1336 marketingWallet = newMarketingWallet; ``` - `newMarketingWallet` is not zero-checked before being used.

LowPotential Sandwich AttacksAcknowledged

A sandwich attack can occur when an attacker notices a transaction involving token swaps or liquidity additions that lacks slippage restrictions or minimum output amount settings. The attacker can exploit this by frontrunning the transaction to purchase one of the assets, thereby manipulating the exchange rate, and then backrunning the transaction to sell the asset for a profit. ```solidity=1499 uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, @> 0, // accept any amount of ETH path, address(this), block.timestamp ); ``` The referenced functions are invoked without setting slippage restrictions or minimum output amounts, making transactions that trigger these functions particularly vulnerable to sandwich attacks, especially when large input amounts are involved.

LowUnused state variableAcknowledged

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 `_holderFirstBuyTimestamp` in `Contract` is never used in `Contract`. ```solidity=1076 mapping(address => uint256) private _holderFirstBuyTimestamp; ``` ```solidity=1052 contract Contract is ERC20, Ownable { ```

Contracts in scope1

AddressChainSource code
0x3b991130eae3cca364406d718da22fa1c3e7c256Chain: EthereumSource code: Verified source

Part of Shrub’s security record

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