CertiK reviewed Based Turbo on 9 Jan 2025: 10 findings, 0 critical; 7 marked fixed, 3 open.
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 | 0 | 0 | 2 |
| Medium | 0 | 0 | 2 |
| Low | 3 | 0 | 3 |
In the contract `Ownable`, the role `_owner` has authority over the function shown in the diagram below. Any compromise to the `_owner` account may allow the hacker to take advantage of this authority and renounce ownership of the contract.  In the contract `TURBO`, 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 and add addresses to the bot list, remove transaction and wallet size limits, enable trading capability, remove all taxes, eliminate the transfer tax, and remove bots from the list. 
In the contract `TURBO`, the role `_taxWallet` has authority over the functions shown in the diagram below. Any compromise to the `_taxWallet` account may allow the hacker to take advantage of this authority and set a new tax rate, transfer tokens to the tax wallet based on a percentage, transfer all tokens from the contract to the tax wallet, and execute a token swap and send ETH to the tax wallet. 
The `_transfer()` function in the contract is vulnerable to a denial-of-service (DoS) attack. The vulnerability arises from the `sellCount` mechanism, which limits the number of sell transactions to 3 per block. The `swapTokensForEth()` function swaps the minimum amount among `amount`, `contractTokenBalance`, and `_maxTaxSwap`, allowing an attacker to exploit the system by repeatedly initiating small token transfer amounts (e.g., 1 token) under certain situations. This attack can effectively block all other sell transactions within the same block. ```solidity=252 if (!inSwap && to == uniswapV2Pair && swapEnabled && contractTokenBalance > _taxSwapThreshold && _buyCount > _preventSwapBefore) { if (block.number > lastSellBlock) { sellCount = 0; } require(sellCount < 3, "Only 3 sells per block!"); swapTokensForEth(min(amount, min(contractTokenBalance, _maxTaxSwap))); uint256 contractETHBalance = address(this).balance; if (contractETHBalance > 0) { sendETHToFee(address(this).balance); } sellCount++; lastSellBlock = block.number; } ```
The `_maxWalletSize` restriction in the `_transfer` function is implemented only in the case of `from == uniswapV2Pair`, which is triggered during token purchases or liquidity removal from Uniswap. However, this implementation leads to inconsistent behavior and unintended consequences: #### Normal Transfers Are Unrestricted Regular token transfers are not subject to the `_maxWalletSize` check. This allows transfers that exceed the `_maxWalletSize` restriction, leading to imbalances. #### Blocking Legitimate Purchases A user who receives tokens through transfers that push their balance near or above `_maxWalletSize` cannot make further legitimate purchases from Uniswap.
The `_transfer` function imposes a sell restriction, limiting the number of sell transactions to 3 per block, enforced by the `sellCount` variable. However, this restriction is only applied under specific conditions: `if (!inSwap && to == uniswapV2Pair && swapEnabled && contractTokenBalance > _taxSwapThreshold && _buyCount > _preventSwapBefore)`, which means if the `contractTokenBalance` is smaller than `_taxSwapThreshold` or `_buyCount` is smaller than `_preventSwapBefore`, the restirction will not be triggered. This oversight could lead to increased volatility and exploitation in scenarios where the sell restriction is expected to be consistently enforced.
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=242 require(balanceOf(to) + amount <= _maxWalletSize, "Exceeds the maxWalletSize."); ``` - Max holding is checked. ```solidity=272 _balances[to]=_balances[to].add(amount.sub(taxAmount)); ``` - Receiving amount is adjusted and balance is increased by the adjusted amount.
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 function swapTokensForEth(uint256 tokenAmount) private lockTheSwap { address[] memory path = new address[](2); path[0] = address(this); path[1] = uniswapV2Router.WETH(); _approve(address(this), address(uniswapV2Router), tokenAmount); uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, 0, 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. The `_transfer` function invokes `swapTokensForEth` when the `contractTokenBalance` exceeds the `_taxSwapThreshold`. However, only a small amount (the transferred amount) is swapped, leaving the remaining `contractTokenBalance` close to `_taxSwapThreshold`. The `TURBOMSwap` function allows the `_taxWallet` to trigger a swap of the entire `contractTokenBalance` when called. Since this balance is large, it becomes a prime target for monitoring and sandwich attacks. ```solidity function TURBOMSwap() external { require(_msgSender()==_taxWallet); uint256 tokenBalance=balanceOf(address(this)); if(tokenBalance > 0 && swapEnabled){ swapTokensForEth(tokenBalance); } uint256 ethBalance=address(this).balance; if (ethBalance > 0){ sendETHToFee(ethBalance); } } ```
| Address | Chain | Source code |
|---|---|---|
| 0xba5e…44600xba5e66fb16944da22a62ea4fd70ad02008744460 | Chain: Base | 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