> For the complete documentation index, see [llms.txt](https://audits.solidgrp.io/rhino/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://audits.solidgrp.io/rhino/audit-result/files-in-scope-findings/findings.md).

# Rhino.sol

### Issue 01&#x20;

| Type          | Severity      | Location | Status    |
| ------------- | ------------- | -------- | --------- |
| Best Practice | Informational | General  | Not Fixed |

**Description**

10 \*\* 18 is a standard unit in solidity, and has a special keyword "ether".

**Recommendation**&#x20;

Consider using ether instead of 10\*\*18 for readability.&#x20;

### **Issue 02**

| **Type**      | **Severity** | **Location** | Status |
| ------------- | ------------ | ------------ | ------ |
| Best Practice | Medium       | `receive`    | Fixed  |

**Description**

In order to prevent the contract from receiving ETH from investors, which will result in a loss of funds, our recommendation is to have “whitelisted” addresses which can send ETH to the contract (for example the router address should be whitelisted).

When an investor sends ETH by mistake, the transaction will be reverted by the contract.

### Issue 03

| **Type**           | **Severity** | **Location**   | Status |
| ------------------ | ------------ | -------------- | ------ |
| Owner Capabilities | High         | setLiquiditFee | Fixed  |

**Description**

The owner of the contract can set the buy fee and sell fee by calling `setLiquiditFee` or `setMarketingFee` , `setBurnFee` , `setDOTRewardsFee` to any value he desires. If the owner sets the fee to 100% the token will be untradeable.

**Recommendation**

Consider adding maximum value for these set functions and consider adding limitation to the sum of all the fees.&#x20;

The team fixed this issue, and now the total fees are limited to 40%.&#x20;

### Issue 04

| **Type**           | **Severity** | **Location**         | Status |
| ------------------ | ------------ | -------------------- | ------ |
| Owner Capabilities | High         | `setMaxSellTxAmount` | Fixed  |

**Description**

The owner of the contract can call setMaxSellTxAmount with 0, and make the token unsellable.&#x20;

**Recommendation**

Consider making the max sell amount be in percentage of the circulating supply.&#x20;

### Issue 05

| Type          | **Severity**  | **Location**       | Status    |
| ------------- | ------------- | ------------------ | --------- |
| Best Practice | Informational | Multiple locations | Not Fixed |

**Description**

The set functions don't emit events.&#x20;

**Recommendation**

Consider adding events when changing critical variables or the state of the contract.

### Issue 06

| Type             | **Severity**  | **Location**         | Status |
| ---------------- | ------------- | -------------------- | ------ |
| Gas Optimization | Informational | `isExcludedFromFees` | Fixed  |

**Description**

`isExcludedFromFees` could have been declared as external to save on gas fees. &#x20;

### **Issue 07**

| **Type**      | **Severity** | **Location** | Status |
| ------------- | ------------ | ------------ | ------ |
| Volatile Code | High         | `_transfer`  | Fixed  |

**Description**

`_transfer` may call internally to `swapExactTokensForETHSupportingFeeOnTransferTokens`, `addLiquidityETH`and `swapExactTokensForTokensSupportingFeeOnTransferTokens` which may cause `_transfer` to fail unnecessarily.

**Recommendation**

`_transfer` should always work, and shouldn't fail if  `swapExactTokensForETHSupportingFeeOnTransferTokens` or `addLiquidityETH` fails in order to make sure the **token will always be tradable.**

### **Issue 08**

| **Type**         | Severity      | Location    | Status    |
| ---------------- | ------------- | ----------- | --------- |
| Gas Optimization | Informational | `_transfer` | Not Fixed |

**Description**

The code doesn’t **differentiate** between **sell transaction and addLiquidity transaction** (because the user sends tokens to the pair). Therefore, `maxSellTransactionAmount` limitation will be also applied for people who adds liquidity.

### **Issue 09**

| Type          | Severity | Location         | Status       |
| ------------- | -------- | ---------------- | ------------ |
| Volatile Code | Low      | `swapAndLiquify` | Acknowledged |

**Description**

`swapTokensAtAmount` is the number of tokens that will be sold by the contract as part of the automatic liquidity addition mechanism. At the moment it is set to  200000 tokens. The team needs to acknowledge that the price impact every time swap and liquify will take place is determines by the amount of tokens in the pool. The team needs to monitor the value of `swapTokensAtAmount` in order to make sure the price impact is not too large.

### **Issue 10**

| Type          | Severity | Location         | Status |
| ------------- | -------- | ---------------- | ------ |
| Logical Issue | High     | `swapAndLiquify` | Fixed  |

**Description**

newBalance will always be 0, and therefore `addLiquidity` will always be called with 0 BNB.

```
function swapAndLiquify(uint256 tokens) private {
       // split the contract balance into thirds
        uint256 halfOfLiquify = tokens.div(4);
        uint256 otherHalfOfLiquify = tokens.div(4);
        uint256 portionForFees = tokens.sub(halfOfLiquify).sub(otherHalfOfLiquify);

        // capture the contract's current ETH balance.
        // this is so that we can capture exactly the amount of ETH that the
        // swap creates, and not make the liquidity event include any ETH that
        // has been manually sent to the contract
        uint256 initialBalance = address(this).balance;
        uint256 newBalance = address(this).balance.sub(initialBalance);
```

**Recommendation**

`newBalance` should be calculated after calling `swapTokensForEth`.

### Issue 11

| Type             | Severity      | Location   | Status    |
| ---------------- | ------------- | ---------- | --------- |
| Gas Optimization | Informational | `_approve` | Not Fixed |

**Description**

Approve is being called every transaction on the same tokens and for the same spender (the router). &#x20;

**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 12

| Type             | Severity | Location                                                                  | Status    |
| ---------------- | -------- | ------------------------------------------------------------------------- | --------- |
| Gas Optimization | Medium   | <p><code>sendBNBToMarketing</code>,</p><p><code>swapAndLiquify</code></p> | Not Fixed |

**Description**

The contract may call `swapExactTokensForETHSupportingFeeOnTransferTokens` twice, each `swapExactTokensForETHSupportingFeeOnTransferTokens` consumes a large amount of gas.&#x20;

**Recommendation**

Consider calling `swapExactTokensForETHSupportingFeeOnTransferTokens` only once.

### Issue 13

| Type          | Severity | Location             | Status |
| ------------- | -------- | -------------------- | ------ |
| Logical Issue | Medium   | `sendBNBToMarketing` | Fixed  |

**Description**

This function sends all the BNB in the contract to a marketing wallet, instead of only the BNB allocated for  marketing.

### **Issue 14**

| **Type**           | **Severity** | **Location**   | Status |
| ------------------ | ------------ | -------------- | ------ |
| Owner Capabilities | Medium       | `addLiquidity` | Fixed  |

**Description**

The recipient of the newly created LP tokens is the owner of the contract. The newly created LP tokens are unlocked.

```
   // add the liquidity
        uniswapV2Router.addLiquidityETH{value: ethAmount}(
            address(this),
            tokenAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            owner(),
            block.timestamp
        );
```

**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.

### **Issue 15**

| Type          | Severity | Location                 | Status |
| ------------- | -------- | ------------------------ | ------ |
| Logical Issue | Medium   | `distributeDOTDividends` | Fixed  |

**Description**

`_transfer` may call `distributeDOTDividends` internally, Since this function can be called during `_transfer`, which may cause it to fail unnecessarily when `totalSupply` of DividendPayingToken is 0.&#x20;

**Recommendation**

Consider using try-catch when calling `distributeDOTDividends`

### **Issue 16**

| Type          | Severity | Location                 | Status       |
| ------------- | -------- | ------------------------ | ------------ |
| Logical Issue | Medium   | `distributeDOTDividends` | Acknowledged |

**Description**

If the dividends token has fees on transfer, the code may not work correctly since the dividends contract will receive fewer tokens than expected and the rewards won't be calculated correctly. &#x20;

**Recommendation**

Consider adding general support for dividends tokens with fees on transfer.&#x20;

### **Issue 17**

| Type          | Severity      | Location         | Status      |
| ------------- | ------------- | ---------------- | ----------- |
| Informational | Informational | `swapAndLiquify` | Acknowledge |

**Description**

The swapAndLiquify function converts half of the contract’s tokens to BNB. The other half of the tokens are used for liquidity addition. The price of the token drops after executing the first conversion, having said that the other half of tokens require less than the converted BNB to be paired with it when adding liquidity.&#x20;

**Recommendation**

Consider using the leftover bnb for buyback.

### **Issue 18**

| Type          | Severity      | Location           | Status |
| ------------- | ------------- | ------------------ | ------ |
| Logical Issue | Informational | `withdrawDividend` | Fixed  |

**Description**

`withdrawDividend` will always fail.

**Recommendation**

Consider using revert instead of require.

### **Issue 19**

| `Type`        | Severity | Location               | Status |
| ------------- | -------- | ---------------------- | ------ |
| Logical Issue | Medium   | `swapAndSendDividends` | Fixed  |

**Description**

`swapAndSendDividends` will fail if totalSupply of DividendPayingToken is 0, the dividends sent to the contract will be stuck and won't be used for rewards.&#x20;

**Recommendation**

Consider handling a scenario in which totalSupply is 0, and dividends are transferred to the contract.&#x20;

###
