As of 3 Nov 2026, Shrub has 1 audit report on Trustblock, by CertiK, dated 29 Nov 2024. That report lists no open critical findings. It also holds 1 deployed contract on 1 chain.
Record last updated . It holds audits, findings and contracts up to Nov 2026, and incidents up to Oct 2026. Trustblock does not review code.
Newest first
| Audit | Security firm | Date | Scope | Critical findings | Report |
|---|---|---|---|---|---|
| Shrub token | Security firm: CertiK | Date: | Scope: 1 address on Ethereum | No open critical findings | Open · skynet.certik.com |
Statuses are the security firm’s own, from each report.
| Severity | Open | Acknowledged | Fixed |
|---|---|---|---|
| Critical | 0 | 0 | 0 |
| High | 1 | 0 | 1 |
| Medium | 0 | 1 | 0 |
| Low | 0 | 9 | 0 |
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; } ```
Open the reportThe `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; } ```
Open the reportThe 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.
Open the reportThe `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.
Open the reportThe 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 }(""); ```
Open the reportThe 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.
Open the reportThere should always be events emitted in the sensitive functions that are controlled by centralization roles.
Open the reportAddresses 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.
Open the reportA 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.
Open the reportSome 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 { ```
Open the report| Address | Chain | Source code |
|---|---|---|
| 0x3b99…c2560x3b991130eae3cca364406d718da22fa1c3e7c256 | Chain: Ethereum | Source code: Verified source |
Is this your project? Show this record on your own website. The label states what the record holds, links to this page and updates by itself. It is free and needs no sign-in.
Automatic: the three strongest facts of this project’s own record (its last audit and two more), highlighted. They update with the record. Picking a fact turns Automatic off.
<head><script src="https://widget.trustblock.run/project-widget.min.js" defer></script></head><body><divdata-tb-project-widgetdata-tb-project-slug="shrub-token"></div></body>
Paste the code where the label should appear. It uses no API credit and updates by itself.
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