CertiK reviewed BenTen Inu (Benten Inu - Audit) on 5 Jun 2023: 13 findings, 0 critical; 1 marked fixed, 3 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 | 1 | 1 |
| Medium | 0 | 2 | 0 |
| Low | 9 | 0 | 0 |
Considering the code snippet provided: ```solidity=530 function changeFee(Taxes memory _taxes) public onlyOwner { require((_taxes.rfi + _taxes.marketing) <= 15, "Tax must lower than 15%"); taxes = _taxes; } ``` It is worth noting that the `_taxes.rfi` and `_taxes.marketing` values can be modified arbitrarily, as long as the condition `(_taxes.rfi + _taxes.marketing) <= 15` is satisfied. However, if the `_taxes.rfi` value is set to 0, the reflection mechanism becomes ineffective, rendering the token no longer deflationary. Consequently, users would still incur transaction fees while other holders would no longer benefit from holding tokens.
In function `transferFrom()`, the `_transfer()` function is executed before checks and updates to the allowance are processed. ```solidity=230 function transferFrom( address sender, address recipient, uint256 amount ) public override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "BEP20: transfer amount exceeds allowance"); _approve(sender, _msgSender(), currentAllowance - amount); return true; } ``` This violates the check-effect-interaction pattern and should follow the checks and updates of the allowances. An added benefit is that having the allowance check `require(currentAllowance >= amount, "BEP20: transfer amount exceeds allowance")` before the execution of the `_transfer()` function (or any checks in general before such external function calls) will save gas since all remaining gas will be returned after the function reverts immediately due to insufficient gas.
The function `changeMarketingWallet()` is used to update the `marketingWallet` address. ```solidity=553 function changeMarketingWallet(address _marketWallet) public onlyOwner { marketingWallet = _marketWallet; } ``` The original `marketingWallet` was excluded from fees, however, there is no mechanism to remove the old `marketingWallet` from the `_isExcludedFromFee` mapping and add the new `marketingWallet` to the `_isExcludedFromFee` mapping. The audit team would like to understand how this wallet update process is handled and recommend implementing the update automatically in the function run.
There should always be events emitted in the sensitive functions that are controlled by centralization roles.
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. ```solidity=536 marketingWallet = _marketWallet; ``` - `_marketWallet` is not zero-checked before being used.
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 back running (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 these functions are vulnerable to sandwich attacks, especially when the input amount is large: - `swapExactTokensForETHSupportingFeeOnTransferTokens()`
State variables that never change should be declared as `constant` to save gas. ```solidity=139 uint256 private _tTotal = 420000000000000000 * 10**_decimals; ``` - `_tTotal` should be declared `constant`. --- ```solidity=144 address public deadWallet = 0x000000000000000000000000000000000000dEaD; ``` - `deadWallet` should be declared `constant`.
The contract cited has an 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 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 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 |
|---|---|---|
| 0x1e8a…d56a0x1e8af416823b1911c6b640a10b817b47f962d56a | 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