CertiK reviewed Babydoge2.0 (Babydoge2.) on 4 Aug 2023: 12 findings, 0 critical; 1 marked fixed, 2 acknowledged, 9 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 | 2 | 1 |
| Medium | 0 | 0 | 0 |
| Low | 9 | 0 | 0 |
In the function `changeLpPair` at the pointed locations, the `newPair` indicated will be added as `lpPair` in the mapping `isLpPair`. Although, there is no way to remove invalid liquidity pool pairs from that mapping in the current codebase.
If the `totalSupply` is zero, the `decimals()` function will revert. Making it impossible for the users to check the decimals of the token.
It is expected that the `totalSupply` function always succeeds, assuming that its execution does not run out of gas. However, the implementation of `totalSupply` in contract Babydoge2 sometimes reverts.
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. in ETH: ```solidity=290 isLpPair[newPair] = true; ``` - `newPair` is not zero-checked before being used. --- ```solidity=328 marketingAddress = payable(marketing); ``` - `marketing` is not zero-checked before being used. --- ```solidity=329 marketing2Address = payable(marketing2); ``` - `marketing2` is not zero-checked before being used. --- ```solidity=329 setPresaleAddress(address presale, bool yesno) ``` - `presale` is not zero-checked before being used. --- In BSC: ```solidity=285 isLpPair[newPair] = true; ``` - `newPair` is not zero-checked before being used. --- ```solidity=322 marketingAddress = payable(marketing2); ``` - `marketing` is not zero-checked before being used. --- ```solidity=367 setPresaleAddress(address presale, bool yesno) ``` - `presale` is not zero-checked before being used. ---
The contract contains a hardcoded gas limit of 35000 for calls to `marketingAddress` and `marketing2Address` within the `internalSwap` function. The Ethereum network requires gas for executing operations, and different operations require different amounts of gas. Hardcoding the gas limit could lead to potential risks in terms of compatibility and functionality during future Ethereum chain upgrades. If the gas requirements for operations change in future Ethereum versions and the hardcoded gas limit is insufficient, these calls will fail. This may disrupt the token's normal functionality, potentially halting the swaps or transfers.
Contract `Babydoge2` 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.
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=182 IRouter02 public swapRouter; ``` - The contract `Babydoge2` interacts with third party contract with `IRouter02` interface via `swapRouter`.
The `success` variable of the `.call` functions in `internalSwap` is not checked. ```solidity=371 if(twoThird > 0) {(success,) = marketingAddress.call{value: twoThird, gas: 35000}("");} if(address(this).balance > 0) {(success,) = marketing2Address.call{value: address(this).balance, gas: 35000}("");} ``` ```solidity=363 if(address(this).balance > 0) {(success,) = marketingAddress.call{value: address(this).balance, gas: 35000}("");} ``` In this way, there is no guarantee that the `call` succeded.
The linked variables assigned in the constructor can be declared as `immutable`. Immutable state variables can be assigned during contract creation but will remain constant throughout the lifetime of a deployed contract. A big advantage of immutable variables is that reading them is significantly cheaper than reading from regular state variables since they will not be stored in storage.
| Address | Chain | Source code |
|---|---|---|
| 0x41b6…46fd0x41b6f91daa1509bfbe06340d756560c4a1d146fd | Chain: Ethereum | Source code: Verified source |
| 0xa4e0…5ca40xa4e068e2b8f58e6c3090174a9e4e95f5bb025ca4 | Chain: Ethereum | Source code: Verified source |
| 0xa4e0…5ca40xa4e068e2b8f58e6c3090174a9e4e95f5bb025ca4 | 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