CertiK reviewed Red Light District Metaverse (Red Light District Metaverse Token - Audit) on 24 Jan 2023: 23 findings, 0 critical; 19 marked fixed, 4 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 | 3 | 0 | 1 |
| Medium | 0 | 0 | 1 |
| Low | 1 | 0 | 17 |
The function `swapAndLiquify()` is used to distribute the fees to various wallets as well as to add liquidity. However, this function is `private` and never used in the contract. Thus it will never be called and cause the fees to not be distributed as designed.
The `_swapAndLiquify()` function converts half of the contracts `RLDM` token balance to `BNB`. The other half of `RLDM` tokens and part of the converted BNB are deposited into the RLDM-BNB pool on pancakeswap as liquidity. For every `swapAndLiquify()` function call, a small amount of BNB is leftover in the contract. This is because the price of `RLDM` drops after swapping the first half of `RLDM` tokens into `BNB`, and the other half of `RLDM` tokens require less than the converted BNB to be paired with it when adding liquidity. The contract doesn't appear to provide a way to withdraw those BNB, and they will be locked in the contract forever.
`_swapAndLiquify()` is called whenever there is a buy, `swapAndLiquifyEnabled = true`, and `inSwapAndLiquify != true`. This can cause an increase in sell pressure as it dramatically increases the number of sells. In addition, it may call `_swapAndLiquify()` when there is very little or no liquidity to be added.
The variables `_totalTaxIfBuying`, `_totalTaxIfSelling`, and `_totalDistributionShares` are assigned both when the variables are defined and in the constructor.
The time-lock of 48 hours is started with an event stating that there was an ownership transfer request which gives the address of the newOwner and the `block.timestamp` when the ownership can be transferred. However, after the 48 hours a different `newOwner` could be given as an input when `transferOwnership()` is called so that the time-lock was initiated for one owner, but then ownership is assigned to another.
Performing integer division before multiplication truncates the low bits, losing the precision of calculation. This is done when calculating all of the total amounts for the initial distribution of tokens.
Buys and sells are taxed, with the tax being broken into liquidity, marketing, and team fees. The percentages stored in these variables is not proportional to the amount of the total fees that gets distributed however. The liquidity, marketing, and team shares instead are used to calculate how the total fees are distributed when `swapAndLiquify()` is called. For example, upon construction liquidity fees account for 2/5 of the total fees. However, the liquidity share is only 1/6 of the total distribution of shares and as a result only approximately 1/6 of the total fees is used for liquidity.
The `public` functions: - `airdrop()` - `setMarketPairStatus()` - `setIsExcludedFromFee()` - `setSwapAndLiquifyEnabled()` - `setSwapAndLiquifyByLimitOnly()` - `changeRouterVersion()` are never called by the contract can be declared `external`. External functions can be more efficient than `public` functions.
There should always be events emitted in the sensitive functions that are controlled by centralization roles. The following functions are controlled by `_owner`: - `airdrop()` - `setMarketPairStatus()` - `setIsExcludedFromFee()` - `setBuyTaxes()` - `setSellTaxes()` - `setDistributionSettings()` - `setMarketingWalletAddress()` - `setTeamWalletAddress()` - `setSwapAndLiquifyByLimitOnly()` - `changeRouterVersion()`
The function `transferToAddressETH()` uses the built in `transfer()` function. There are potential issues with this as this forwards exactly 2300 gas and if the receiving contract has a `fallback` function or gas prices are changed, then the transaction may be reverted. See this [doc](https://ethereum.stackexchange.com/questions/19341/address-send-vs-address-transfer-best-practice-usage) for more details.
The `gnosisSafeProxy` is given ownership last in the constructor. This causes the `owner()` to be the zero address when used in the rest of the constructor. In addition, ownership is assigned by using the `_transferOwnership()` function that will start the 48 hour time-lock so that ownership can be transferred after 48 hours of contract deployment.
If `address(this)` is changed to not be excluded from fees, then with the current implementation the `swapAndLiquify` transaction can be taxed.
*This finding has a minor impact because the reentrancy only causes out-of-order events.* A reentrancy attack can occur when the contract creates a function that makes an external call to another untrusted contract before resolving any effects. If the attacker can control the untrusted contract, they can make a recursive call back to the original function, repeating interactions that would have otherwise not run after the external call resolved the effects. In this case it is possible to reenter `changeRouterVersion()`, `transfer()`, and `transferFrom()` and emit events out of order if the router is changed to an untrusted contract controlled by an attacker.
Solidity version >=0.8.0 includes checked arithmetic operations and underflow/overflow by default, making SafeMath redundant.
Literals with many digits are difficult to read and review.
The events `SwapAndLiquify` and `SwapETHForTokens` are declared but never used.
The import file `IUniswapV2Pair.sol` is never used in the contract.
The bool `swapAndLiquifyByLimitOnly` is defined, but is never used in the contract except in the function `setSwapAndLiquifyByLimitOnly` that is used to update the bool.
The variable `deadAddress` could be declared as `constant` because it is never modified.
The report names a repository or files. Open the report to see its scope.
Repository and files the report names (5)
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