> For the complete documentation index, see [llms.txt](https://audits.solidgrp.io/blitz-launchpad/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/blitz-launchpad/audit-results/findings/presalemaster.sol.md).

# preSaleMaster.sol

## **Issue 01**

| **Type**      | **Severity**                             | **Location**        | **Status**                                     |
| ------------- | ---------------------------------------- | ------------------- | ---------------------------------------------- |
| Logical Issue | <mark style="color:red;">**High**</mark> | `initializePresale` | <mark style="color:green;">**Resolved**</mark> |

**Description**

There is no guarantee that the owner deposits will satisfy the presale and liquidity rates.

## **Issue 02**

<table data-header-hidden><thead><tr><th width="196">Type</th><th>Severity </th><th>Location</th><th></th></tr></thead><tbody><tr><td><strong>Type</strong></td><td><strong>Severity</strong> </td><td><strong>Location</strong></td><td><strong>Status</strong></td></tr><tr><td>Best Practice</td><td><mark style="color:green;"><strong>Informational</strong></mark></td><td><code>contribute</code></td><td><mark style="color:green;"><strong>Resolved</strong></mark></td></tr></tbody></table>

**Description**

Use a modifier instead of the presale `require` statement for better readability

## **Issue 03**

| **Type**      | **Severity**                                  | **Location** | **Status**                                     |
| ------------- | --------------------------------------------- | ------------ | ---------------------------------------------- |
| Volatile Code | <mark style="color:orange;">**Medium**</mark> | `contribute` | <mark style="color:green;">**Resolved**</mark> |

**Description**

The `investor` array's size is limitless. Iterating over an unbounded array may cause the transaction to hit the block gas limit.

**Recommendation**

Use a mapping to track contributions.

## **Issue 04**

| **Type**      | **Severity**                                  | **Location**      | **Status**                                     |
| ------------- | --------------------------------------------- | ----------------- | ---------------------------------------------- |
| Best Practice | <mark style="color:orange;">**Medium**</mark> | `claim, finalize` | <mark style="color:green;">**Resolved**</mark> |

**Description**

The functions call external contracts, exposing themselves to potential reentrancy attacks.&#x20;

The code does not follow [check effect interactions](https://fravoll.github.io/solidity-patterns/checks_effects_interactions.html) pattern.&#x20;

**Recommendation**

Add a reentrancy guard or follow check-effect interactions pattern. (read general recommendation)

## **Issue 05**

| **Type**      | **Severity**                             | **Location**         | **Status**                                     |
| ------------- | ---------------------------------------- | -------------------- | ---------------------------------------------- |
| Volatile Code | <mark style="color:red;">**High**</mark> | `withdrawContribute` | <mark style="color:green;">**Resolved**</mark> |

**Description**

The function does not change the user's deposit value, hence any user can withdraw their deposit multiple times and drain the contract.

**Recommendation**

Add a require statements that makes sure the user can withdraw their deposit and set `deposits[msg.sender]` to 0 after the withdrawal.

## **Issue 06**

| **Type**      | **Severity**                               | **Location**         | **Status**                                     |
| ------------- | ------------------------------------------ | -------------------- | ---------------------------------------------- |
| Logical Issue | <mark style="color:yellow;">**Low**</mark> | `withdrawContribute` | <mark style="color:green;">**Resolved**</mark> |

**Description**

The function does not remove the user from the `investors` array.

## **Issue 07**

| **Type**           | **Severity**                               | **Location** | **Status**                                     |
| ------------------ | ------------------------------------------ | ------------ | ---------------------------------------------- |
| Owner Capabilities | <mark style="color:yellow;">**Low**</mark> | `finalize`   | <mark style="color:green;">**Resolved**</mark> |

**Description**

The owner can lock funds in the contracts by never calling this function if the presale exceeds `softcap`

## **Issue 08**

| **Type**      | **Severity**                                        | **Location** | **Status**                                       |
| ------------- | --------------------------------------------------- | ------------ | ------------------------------------------------ |
| Volatile Code | <mark style="color:green;">**Informational**</mark> | `finalize`   | <mark style="color:red;">**Not Resolved**</mark> |

**Description**

The function calls `sendValue` multiple times. However, these calls may fail by the recipient, reverting the entire transaction.

**Recommendation**

Consider wrapping these calls inside try-catch or change the `sendValue` mechanism into a `withdraw` function that will be called by the recipients.

## **Issue 09**

| **Type**      | **Severity**                             | **Location** | **Status**                                     |
| ------------- | ---------------------------------------- | ------------ | ---------------------------------------------- |
| Logical Issue | <mark style="color:red;">**High**</mark> | `finalize`   | <mark style="color:green;">**Resolved**</mark> |

**Description**

The contract multiplies `listingRate` by the amount of amount to get the number of tokens. Therefore, `listingRate` should be calculated as token/ETH (token per ETH). However it is currently calculated as ETH/token (ETH per token)

## **Issue 10**

| **Type**      | **Severity**                             | **Location** | **Status**                                     |
| ------------- | ---------------------------------------- | ------------ | ---------------------------------------------- |
| Logical Issue | <mark style="color:red;">**High**</mark> | `finalize`   | <mark style="color:green;">**Resolved**</mark> |

**Description**

`listingRate` does not subtract the fees taken from the amount listed. Consequently, users may be unable to withdraw their tokens from the contract as the amount of tokens listed does not match the actual amount of tokens in the contract.

## **Issue 11**

| **Type**      | **Severity**                               | **Location** | **Status**                                     |
| ------------- | ------------------------------------------ | ------------ | ---------------------------------------------- |
| Logical Issue | <mark style="color:yellow;">**Low**</mark> | `finalize`   | <mark style="color:green;">**Resolved**</mark> |

**Description**

If a liquidity pool already exists, there may unrecoverable leftover tokens in the contract.&#x20;

## **Issue 12**

| **Type**         | **Severity**                                        | **Location**   | **Status**                                     |
| ---------------- | --------------------------------------------------- | -------------- | ---------------------------------------------- |
| Gas Optimization | <mark style="color:green;">**Informational**</mark> | `addWhitelist` | <mark style="color:green;">**Resolved**</mark> |

**Description**

Move the following line into the `if` block to avoid storing the value in storage.

```
whiteList[accounts[index]] = true;
```

## **Issue 13**

<table data-header-hidden><thead><tr><th>Type</th><th width="150">Severity </th><th>Location</th><th></th></tr></thead><tbody><tr><td><strong>Type</strong></td><td><strong>Severity</strong> </td><td><strong>Location</strong></td><td><strong>Status</strong></td></tr><tr><td>Gas Optimization</td><td><mark style="color:green;"><strong>Informational</strong></mark></td><td><code>removeWhitelist</code></td><td><mark style="color:red;"><strong>Not Resolved</strong></mark></td></tr></tbody></table>

**Description**

The removal can be done in constant time by passing the indexes if the accounts to remove.

## **Issue 14**

| **Type**      | **Severity**                             | **Location**      | **Status**                                     |
| ------------- | ---------------------------------------- | ----------------- | ---------------------------------------------- |
| Logical Issue | <mark style="color:red;">**High**</mark> | `getVestedAmount` | <mark style="color:green;">**Resolved**</mark> |

**Description**

`listingRate` is multiplied by a factor.

## **Issue 15**

| **Type**      | **Severity**                                  | **Location**      | **Status**                                     |
| ------------- | --------------------------------------------- | ----------------- | ---------------------------------------------- |
| Volatile Code | <mark style="color:orange;">**Medium**</mark> | `getVestedAmount` | <mark style="color:green;">**Resolved**</mark> |

**Description**

The function may be called anytime. Should the function be called before `presaleEndTimestamp`, `(now - presaleEndTimeStamp)` will underflow.

## **Issue 16**

| **Type**      | **Severity**                             | **Location**         | **Status**                                     |
| ------------- | ---------------------------------------- | -------------------- | ---------------------------------------------- |
| Logical Issue | <mark style="color:red;">**High**</mark> | `withdrawContribute` | <mark style="color:green;">**Resolved**</mark> |

**Description**

deposits\[msg.sender] is zeroed and then sent out as the value, so users will always withdraw 0 tokens - the value must be kept aside before zeroing it out.

```
deposits[msg.sender] = 0;
Address.sendValue(msg.sender, deposits[msg.sender]);
```
