CertiK reviewed Baby Elon (BabyElon - Audit 1) on 22 Jan 2024: 10 findings, 0 critical; 2 marked fixed, 8 open.
The original report was removed from its address (seen 20 Oct 2026).
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 | 1 |
| Medium | 0 | 0 | 0 |
| Low | 6 | 0 | 1 |
The **internalSwap()** function calls the `swapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens()` function to swap the **BabyElon** tokens to BNB/ETH and send the BNB/ETH to the `marketingAddress` address. As a result, over time the `marketingAddress` address will accumulate a significant portion BNB/ETH. Since the `marketingAddress` is an EOA (Externally Owned Account), the mishandling of its private key can have devastating consequences for the project as a whole. For the common deflationary token, the entire tokenomic requires certain liquidity to support. However, in the current implementation, the swapped BNB is transferred to `marketingAddress` and is not being used for adding liquidity. Therefore, the entire tokenomic may crash due to a lack of enough liquidity in the pool.
All of the BabyElon tokens are sent to the contract deployer. This is a centralization risk because the deployer can distribute tokens without obtaining the consensus of the community. Any compromise to these addresses may allow a hacker to steal and sell tokens on the market, resulting in severe damage to the project.
In the constructor, the `marketingAddress` is set when the `AX.checkDeployer()` returns false. Otherwise, the `marketingAddress` will not be set and the `isContract` will be set to true. However, the `isContract` is not used anywhere and we are not clear about the relationship between if and else conditions.
A sandwich attack may happen when an attacker observes a transaction swapping tokens or adding liquidity without setting restrictions on slippage or minimum output amount. The attacker can manipulate the exchange rate by frontrunning (executing before the target) a transaction to purchase one of the assets and make profits by backrunning (executing after the target) a transaction to sell the asset. The following function is called without setting restrictions on slippage or minimum output amount, so transactions triggering the function is vulnerable to sandwich attacks, especially when the input amount is large: - `swapRouter.swapExactTokensForETHSupportingFeeOnTransferTokens()`
Contract `BabyElon` is vulnerable to [a known ERC20 race condition issue](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729), which could lead to token theft. When a user calls `approve()` for a second time on a spender that has already been allowed, the spender could call `transferFrom()` to transfer the previous value and still receive the authorization to transfer the new value. Exploit scenario: 1. Alice calls `approve(Bob, 100)` to allow Bob to spend 100 tokens. 2. Alice changes her mind and calls `approve(Bob, 50)`. 3. Bob observes the second `approve(Bob, 50)` function call and calls `transferFrom(Alice, Bob, 100)` before the second `approve(Bob, 50)` call. 4. The above scenario can be achieved by front-running. In this case, Bob can transfer another 50 tokens from Alice and in total, he transferred 150 tokens from Alice.
The linked statements do not affect the functionality of the codebase and appear to be either remnants of test code or older functionality.
In the function `_transfer()`, the conditions to trigger the maxWallet check are as below: First of all, the internal function `isLimitedAddress()` contains a condition as `msg.sender != owner()`, this means the owner can use the `transferFrom()` function to avoid this check for normal users. ```solidity function isLimitedAddress(address ins, address out) internal view returns (bool) { bool isLimited = ins != owner() && out != owner() && msg.sender != owner() && !liquidityAdd[ins] && !liquidityAdd[out] && out != address(0) && out != address(this); return isLimited; } ``` Secondly, the below statement contains multiple conditions, we can split them into two parts, the requirement is either part 1 or part 2 is true. ```solidity if(!isLpPair[to] && from != address(this) && to != address(this) || is_transfer(from,to) && !avoidMaxTxLimits) { require(balanceOf(to) + amount <= maxWallet,"maxWallet is 1%"); } ``` part 1: `!isLpPair[to] && from != address(this) && to != address(this)` It represents non-sell and is unrelated to the `address(this)`, which means no need to have this check for sell and swap by `address(this)`. or part 2: `is_transfer(from,to) && !avoidMaxTxLimits` It represents it's a normal transfer(non-buy/non-sell) and the `avoidMaxTxLimits` flag is false.
The contract is serving as the underlying entity to interact with one or more third party protocols. The scope of the audit treats third party entities as black boxes and assumes their functional correctness. However, in the real world, third parties can be compromised and this may lead to lost or stolen assets. In addition, upgrades of third parties can possibly create severe impacts, such as increasing fees of third parties, migrating to new LP pools, etc. ```solidity=194 IRouter02 public swapRouter; ``` - The contract `BabyElon` interacts with third party contract with `IRouter02` interface via `swapRouter`. --- ```solidity=205 AntiBot private AX; ... AX = AntiBot(0x03eD568bb6e426881392f411F4cfe766Fe2fc43A); ``` - The contract `BabyElon` interacts with third party contract with `AntiBot` interface via `AX` and the contract at address `0x03eD568bb6e426881392f411F4cfe766Fe2fc43A` is unverified.
| Address | Chain | Source code |
|---|---|---|
| 0x2589…dd980x258903a8e68d5248de85cf8a0a173d9e046edd98 | 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