CertiK reviewed DEBT Box (Grow) on 13 Apr 2023: 17 findings, 0 critical; 2 acknowledged, 15 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 | 0 |
| Medium | 0 | 0 | 0 |
| Low | 15 | 0 | 0 |
One or more declarations do not conform to the [Solidity style guide](https://solidity.readthedocs.io/en/v0.7.3/style-guide.html#naming-conventions) with regards to its naming convention. Particularly: - `camelCase`: Should be applied to function names, argument names, local and state variable names, modifiers - `UPPER_CASE`: Should be applied to `constant` variables - `CapWords`: Should be applied to contract names, struct names, event names and enums
The `GROW` contract uses `Pancakeswap` for swapping and adding liquidity to `Pancakeswap` pool, but naming it `Uniswap`. Function `swapTokensForEth(uint256 tokenAmount)` swaps `YUMMY` token for BNB instead of ETH.
The functions which are never called internally within the contract should have external visibility for gas optimization.
The highlighted comment does not reflect what the function below is doing.
The contract has one payable function, but does not have a function to withdraw the funds.
There should always be events emitted in the sensitive functions that are controlled by centralization roles.
It is highly recommended NOT to include OpenZeppelin library code directly in source code, but import the original library to minimize risk because even slight changes to the library code may lead to critical/major vulnerabilities/bugs. For Solidity version 0.8.x, the latest OpenZeppelin version 4.7.3 should be used.
The `approve` function could be used in an attack that allows a spender to transfer more tokens than the owner of the tokens ever wanted to allow the spender to transfer. Here is a possible attack scenario: Alice allows Bob to transfer N of Alice's tokens (N>0) by calling `approve()` method on `Grow` smart contract passing Bob's address and N as method arguments. After some time, Alice decides to change from N to M (M>0) the number of Alice's tokens Bob is allowed to transfer, so she calls approve method again, this time passing Bob's address and M as method arguments. Bob notices Alice's second transaction before it was mined and quickly sends another transaction that calls `transferFrom()` method to transfer N Alice's tokens somewhere. If Bob's transaction is executed before Alice's transaction, then Bob will successfully transfer N Alice's tokens and will gain the ability to transfer another M tokens. Before Alice noticed that something went wrong, Bob calls `transferFrom()` method again, this time to transfer M Alice's tokens. So, Alice's attempt to change Bob's allowance from N to M (N>0 and M>0) made it possible for Bob to transfer N+M of Alice's tokens, while Alice never wanted to allow so many of her tokens to be transferred by Bob. ERC20 API: An Attack Vector on Approve/TransferFrom Methods: https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/edit#heading=h.m9fhqynw2xvt
A sandwich attack might 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 (before the transaction being attacked) a transaction to purchase one of the assets and make profits by backrunning (after the transaction being attacked) a transaction to sell the asset. The `swapExactTokensForETHSupportingFeeOnTransferTokens()` function is called without setting restrictions on slippage or minimum output amount, so transactions triggering this function are vulnerable to sandwich attacks, especially when the input amount is large.
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 assume 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. The contract `GROW` interacts with third party contract with `IUniswapV2Router02` interface via `uniswapV2Router`: ```solidity=472 IUniswapV2Router02 public uniswapV2Router; ```
Literals with many digits are difficult to read and review.
The contract has unlocked compiler version. An unlocked compiler version in the source code of the contract permits the user to compile it at or above a particular version. This, in turn, leads to differences in the generated bytecode between compilations due to differing compiler version numbers. This can lead to an ambiguity when debugging as compiler specific bugs may occur in the codebase that would be hard to identify over a span of multiple compiler versions rather than a specific one.
The `_transfer()` function uses the magic number `20` as the fee for the council and dividend.
Variables `_name`, `_symbol`, `_decimals` and `_initialSupply` could be declared as `constant` since these state variables are hardcoded in the constructor and never to be changed.
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 |
|---|---|---|
| 0x3f37…cbed0x3f3701e818a560eacd6fca1477e36b9338a2cbed | 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