> For the complete documentation index, see [llms.txt](https://audits.solidgrp.io/dreams-quest/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/dreams-quest/audit-results/vesting-contract.md).

# Vesting Contract

### **Issue 01**

<table data-header-hidden><thead><tr><th width="235">Type</th><th width="150">Severity</th><th>Location</th><th>Status</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>Owner Capabilities</td><td>High</td><td>addInvestor</td><td></td></tr></tbody></table>

**Description**

The owner of the contract can call addInvestor which will add an address to the vesting contract. The vesting contract is minting tokens for each investor, therefore the team can use this ability to mint tokens.

**Recommendation**

Our recommendation is to transfer the ownership to a timelock contract in order to delay the execution of such methods or to mint all tokens beforehand and remove minting functionality from the vesting contract.

## Issue 02&#x20;

<table data-header-hidden><thead><tr><th>Type</th><th width="152">Severity</th><th>Location</th><th>Status</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>Informational</td><td>_calculateUnlockedTokens</td><td><mark style="color:green;">Resolved</mark></td></tr></tbody></table>

**Description**

This function calculates the amount of unlocked tokens for investor.&#x20;

**Recommendation:**

Consider making this function public in order to have a way for investors to get the amount of tokens unlocked. &#x20;

## Issue 03

<table data-header-hidden><thead><tr><th width="235">Type</th><th width="150">Severity</th><th>Location</th><th>Status</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>High</td><td>global variables</td><td><mark style="color:green;">Resolved</mark></td></tr></tbody></table>

**Description**

&#x20;isFinalized unused.&#x20;

**Recommendation**

Remove unused variables and functions from the code to save on gas fees and storage.

## Issue 04

<table data-header-hidden><thead><tr><th width="235">Type</th><th width="150">Severity</th><th>Location</th><th>Status</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>Medium</td><td>withdrawTokens</td><td><mark style="color:green;">Resolved</mark></td></tr></tbody></table>

**Description**

The function withdrawTokens mint tokens for the investor.

Consider adding a sanity check that checks the investor didn't withdraw more than the initial allocation in this function.

## Issue 05

<table data-header-hidden><thead><tr><th width="235">Type</th><th width="150">Severity</th><th>Location</th><th>Status</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>Logical Issue</td><td>Informational</td><td>startTime</td><td><mark style="color:green;">Resolved</mark></td></tr></tbody></table>

**Description**

startTime is not accurate since the starting time is \_initialTimeStamp.

**Recommendation**

consider changing the return value in getInvestorStartTime to the initial timestamp.

## Issue 06

<table data-header-hidden><thead><tr><th width="235">Type</th><th width="150">Severity</th><th>Location</th><th>Status</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/Best Practice</td><td>Informational</td><td>startTime</td><td><mark style="color:green;">Resolved</mark></td></tr></tbody></table>

**Description**

The variable \_totalAllocatedAmount is not used in the code, and is declared as private.

**Recommendation**

Consider making it public.&#x20;

## Issue 07

<table data-header-hidden><thead><tr><th width="235">Type</th><th width="150">Severity</th><th>Location</th><th>Status</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>Informational</td><td>getInitialTimestamp</td><td><mark style="color:green;">Resolved</mark></td></tr></tbody></table>

**Description**

getInitialTimestamp is not called in the contract.

**Recommendation**

Consider declaring it external to save on gas fees.&#x20;

## Issue 08

<table data-header-hidden><thead><tr><th width="235">Type</th><th width="150">Severity</th><th>Location</th><th>Status</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>Logical Issue / Gas Optimization</td><td>Informational</td><td><p></p><p>_calculateUnlockedTokens</p></td><td><mark style="color:green;">Resolved</mark></td></tr></tbody></table>

**Description**

```
   require(
            investor.withdrawnTokens <= investor.tokensAllotment,
            "withdrawTokens: investor has already withdrawn all available balance"
        );

```

This require statement should make sure the withdrawn amount of tokens is strictly lower than the allotment not lower equal to.&#x20;

## General Notes &#x20;

1. Consider adding a function that will return useful data for investors in one call  - for example, total allocation, amount of unlocked tokens, next unlock time, end of cliff timestamp and end of vesting timestamp.
2. From our experience, investors don't expect vesting contracts to mint tokens this can create a scenario where less tech-savvy users won't understand the tokenomics and why tokens keep being minted from different contracts. We strongly recommend to mint all vested tokens before vesting starts and simply distributing them in the vesting contract.&#x20;
3. &#x20;Consider adding a way to edit vesting data before vesting starts (when not initialized).&#x20;
