Findings
Issue 01
Owner Capabilities
High
lock
, unlock
Fixed
Description
An owner can gain ownership of the contract even if he calls renounceOwnership function.
This can be achieved by performing the following steps:
The owner of the contract can call lock() to lock the contract (the lock function saves the previous owner into a variable)
After the locking period has passed the owner of the contract can call unlock() and regain the ownership.
The owner of the contract can then call the renounceOwnership function. Now, the contract allegedly has no owner (users can verify it by looking for the renounceOwnership transaction and making sure that the owner is set to the zero address)
Recommendation:
Our recommendation Is to remove the lock and unlock function if not needed
Issue 02
Gas Optimization
Informational
All
Not Fixed
Description
approve is being called on every transaction which automatically contributes liquidity to the pool, on the same tokens and for the same spender (the router).
Recommendation
In order to reduce gas costs, approve
could be called once (with max int), and then check if it is needed again using allowance
.
Issue 03
Volatile Code
High
_transfer
Fixed
Description
_transfer
may call internally to swapExactTokensForETHSupportingFeeOnTransferTokens
,addLiquidityETH
and swapExactETHForTokensSupportingFeeOnTransferTokens
Since this function can be called during _transfer
, it may cause _transfer
to fail unnecessarily.
Recommendation
_transfer
should always work, and shouldn't fail if swapExactTokensForETHSupportingFeeOnTransferTokens
or addLiquidityETH
or any other router related fails in order to make sure the token will always be tradable.
Issue 04
Best Practice
Medium
receive
Not Fixed
Description
There is a receive function in the contract, which means any address can send BNB to the contract. The problem is that there is no way to recover BNB that were mistakenly sent to the contract.
Recommendation
In order to prevent the contract from receiving BNB from investors, which will result in a loss of funds, our recommendation is to only accept ETH from “whitelisted” addresses (for example the router address should be whitelisted). The receive function will revert if the address is not whitelisted.
Issue 05
Owner Capabilities
High
setLiquidityFeePromille
, setTaxFeePromille
Fixed
Description
The owner of the contract can set the liquidity fee and tax fee by calling setLiquidityFeePromille
and setTaxFeePromille
to any value he desires. If the owner sets the fee to 100% the token will be untradeable.
Recommendation
Consider adding an upper limit to the set functions.
Issue 06
Logical Issue
High
_transfer
Fixed
Description
The code does not emit events when transferring fees. This can cause blockchain explorers and DApps to inaccurately parse transfers and transactions
Recommendation
Add Transfer event when taking fees.
Issue 07
Lack of Events
Informational
All
Not Fixed
Description
set functions don't emit events.
Recommendation
Consider emitting events when changing the state of the contract.
Issue 08
Owner Capabilites
High
setRouterAddress
Fixed
Description
The owner can set PancakeSwap's router address, which gives him full control over all token swaps.
Recommendation
Consider implementing a timelock mechanism to allow users to review the changes, or remove this feature altogether as backward-incompatible router updates are a very rare event.
Issue 09
Owner Capabilites
High
setMaxWalletToken, setSellTransactionAmount
Fixed
Description
The owner can call setMaxWalletToken
or setSellTransactionAmount
with 0, which will make the token unsellable.
Recommendation
add a require statement to the set function that will prevent setting _maxSellTransactionAmount
and _maxWalletToken
to 0.
Issue 10
Owner Capabilites / Volatile Code
Medium
_getCurrentSupply
Fixed
Description
The _excluded
array can grow indefinitely. _transfer
calls getCurrentSupply
function which iterates over _excluded
array. Iterating over an unbounded array can exceed the block gas limit which will make the token untradable.
Recommendation
One possible solution is to limit the number of excluded addresses. We encourage the owner of the project and the community to frequently monitor the number of excluded addresses. The issue described could be recovered by calling includeInReward
which removes an element from the _excluded array.
Issue 11
Logical Issue
Medium
includeInReward
Fixed
Description:
The code is vulnerable to the SafeMoon bug - excluding an address from the fee and then later including it back will cause the address to receive all RFI rewards for the time it was excluded (at the expense of other holders).
In includeInReward
_rOwned is not updated. _rOwned should be updated and be calculated according to the current rate.
Recommendation:
Properly calculate _rOwned of the included address in includeInReward
based on its _tOwned amount.
Issue 12
Logical Issue
Informational
_transfer
Fixed
Description
According to our discussion with the dev team the purpose of this condition is to prevent the swap and liquidity feature on a regular transfer. However, this statement will be true on regular transfers as well making the swap and liquidity feature execute on transfer transactions as well.
1(doSwapForRouter || (from != _routerAddress && to != _routerAddress))
Recommendation
Consider using msg.sender for making this observation or to change the if condition to
to == pancakeswapV2Pair
Issue 13
Owner Capabilities
Medium
addLiquidity
Not Fixed
Description
The recipient of the newly created LP tokens is the owner of the contract. The newly created LP tokens are unlocked.
Recommendation
Our recommendation is to change the recipient of the newly created LP tokens to the contract in order to ensure that the LP tokens are locked or to simply locked the tokens in the contract for a certain period.
Last updated