CertiK reviewed Baby Neiro on 20 Dec 2024: 19 findings, 0 critical; 4 marked fixed, 13 acknowledged, 2 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 | 2 | 0 | 0 |
| Medium | 0 | 5 | 0 |
| Low | 0 | 8 | 4 |
Try-Catch is used when calling `addLiquidityETH()`, with a revert caught and returning instead of reverting the transaction. However, prior to this call, an amount of tokens are swapped for native tokens. This action will not be reverted and this amount of native token will remain in the contract. While this amount can be rescued, it is not ensured to be allocated to liquidity. In addition, the accounting variables `tokensForTax` are not adjusted, so that they do not handle the amount of tokens that were converted and not succesfully added to liquidity.
Some restrictions can be bypassed by swapping tokens to the router and then getting tokens from the router. When the tokens are transferred to the router, the attacker uses the feature of the router function ***`removeLiquidityETHSupportingFeeOnTransferTokens`***, which will send all the specified tokens in the router to a specified address. Because the router is not supposed to receive tokens for any user other than remove liquidity.
The check `require(_holderLastTransferBlock[tx.origin] + 30 < block.number, "Transfer Delay");` is used to try to delay transfers. However, as `tx.origin` is used, a user can avoid this delay by giving approval to different accounts, which can then transfer tokens on their behalf via `transferFrom()`. As the other accounts execute a transaction to call `transferFrom()`, they will be the `tx.origin`, and thus not be subjected to the delay of others.
The linked statement transfers the native token leftovers in `BabyNeiro` contract. Because the `address.call()` function returns false if the aforementioned transaction is failed, the local variable `success` should be checked or using `address.transfer()` which reverts when transaction is failed.
The smart contract does not check or store the return value of an external call in a local or state variable, which may introduce vulnerabilities due to the unhandled outcome. ```solidity=856 try dexRouter.addLiquidityETH{value: newBalance}( address(this), secondMath, 0, 0, DEAD, block.timestamp ){} catch {return;} ```
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 necessarily be included in the max holding. ```solidity=768 require(amount + balanceOfTo <= _txLimits.walletLimit, "Max Wallet"); ``` - Max holding is checked. ```solidity=746 amount -= handleTax(from, to, amount); ``` - Receiving amount is adjusted. ```solidity=302 _balances[to] += amount; ``` - Balance is increased by the adjusted amount.
Privileged functions should include emittance of corresponding events.
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. 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.
If `newNumInTokens` is too high in functions `updateWalletLimit()` or `updateTransactionLimit()` then the multiplication of the value by `10**decimals()` will cause an overflow when casting the value to type `uint128`.
Transaction limits are only checked if one of the addresses involved in the transfer are not exempt from fees. Some addresses may be set to be exempt from fees but still have a transaction limit. For example, the `dexRouter` is set to be exempt from fees, but is not exempt from transaction limits.
Value `doNothing` is initialized at 0 and can be updated by anyone to add a value of 2 to its previous state each time it is called. It appears variable `doNothing` is not used within the contract. It appears variable `antiMevEnabled` is not used within the contract.
The smart contract contains one or more values that are not used, which can lead to unnecessary complexity and reduced maintainability. ```solidity=866 totalTokensToSwap -= tokensForTaxMem.tokensForLiquidity; ``` - The variable `totalTokensToSwap` is never used after this update.
If the call to `addLiquidityETH` fails during the try-catch logic, then the function `convertTaxes()` will return without further update. This will cause an inconsistency because `contractBalance` and `totalTokensToSwap` will not be updated even though about half of the `liquidityTokens` has been removed through the prior call to `swapTokensForETH(firstmath)`.
| Address | Chain | Source code |
|---|---|---|
| 0x6cdd…c4540x6cdd08de79231a1957f205a3fe5cf9dbf4b0c454 | 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