# MultiMerkleDistributor

### Storage

#### questRewardToken

```solidity
mapping(uint256 => address) questRewardToken
```

Mapping listing the reward token associated to each Quest ID

#### rewardTokens

```solidity
mapping(address => bool) rewardTokens
```

Mapping of tokens this contract is or was distributing

#### questClosedPeriods

```solidity
mapping(uint256 => uint256[]) questClosedPeriods
```

List of Closed QuestPeriods by Quest ID

#### questMerkleRootPerPeriod

```solidity
mapping(uint256 => mapping(uint256 => bytes32)) questMerkleRootPerPeriod
```

Merkle Root for each period of a Quest (indexed by Quest ID)

#### questRewardsPerPeriod

```solidity
mapping(uint256 => mapping(uint256 => uint256)) questRewardsPerPeriod
```

Amount of rewards for each period of a Quest (indexed by Quest ID)

#### questBoard

```solidity
address questBoard
```

Address of the QuestBoard contract

### Events

#### Claimed

```solidity
event Claimed(uint256 questID, uint256 period, uint256 index, uint256 amount, address rewardToken, address account)
```

Event emitted when a user Claims

#### NewQuest

```solidity
event NewQuest(uint256 questID, address rewardToken)
```

Event emitted when a New Quest is added

#### QuestPeriodUpdated

```solidity
event QuestPeriodUpdated(uint256 questID, uint256 period, bytes32 merkleRoot)
```

Event emitted when a Period of a Quest is updated (when the Merkle Root is added)

### Modifiers

#### onlyAllowed

```solidity
modifier onlyAllowed()
```

Check the caller is either the admin or the QuestBoard contract

### Constructor

```solidity
constructor(address _questBoard) public
```

### View Methods

#### isClaimed

```solidity
function isClaimed(uint256 questID, uint256 period, uint256 index) public view returns (bool)
```

Checks if the rewards were claimed for a user on a given period

*Checks if the rewards were claimed for a user (based on the index) on a given period*

**Parameters**

| Name    | Type    | Description                    |
| ------- | ------- | ------------------------------ |
| questID | uint256 | ID of the Quest                |
| period  | uint256 | Amount of underlying to borrow |
| index   | uint256 | Index of the claim             |

**Return Values**

| Name | Type | Description                    |
| ---- | ---- | ------------------------------ |
| \[0] | bool | bool : true if already claimed |

#### getClosedPeriodsByQuests

```solidity
function getClosedPeriodsByQuests(uint256 questID) external view returns (uint256[])
```

Returns all current Closed periods for the given Quest ID

*Returns all current Closed periods for the given Quest ID*

**Parameters**

| Name    | Type    | Description     |
| ------- | ------- | --------------- |
| questID | uint256 | ID of the Quest |

**Return Values**

| Name | Type       | Description                         |
| ---- | ---------- | ----------------------------------- |
| \[0] | uint256\[] | uint256\[] : List of closed periods |

### State-changing Methods

#### claim

```solidity
function claim(uint256 questID, uint256 period, uint256 index, address account, uint256 amount, bytes32[] merkleProof) public
```

Claims the reward for a user for a given period of a Quest

*Claims the reward for a user for a given period of a Quest if the correct proof was given*

**Parameters**

| Name        | Type       | Description                              |
| ----------- | ---------- | ---------------------------------------- |
| questID     | uint256    | ID of the Quest                          |
| period      | uint256    | Timestamp of the period                  |
| index       | uint256    | Index in the Merkle Tree                 |
| account     | address    | Address of the user claiming the rewards |
| amount      | uint256    | Amount of rewards to claim               |
| merkleProof | bytes32\[] | Proof to claim the rewards               |

#### ClaimParams

```solidity
struct ClaimParams {
  uint256 questID;
  uint256 period;
  uint256 index;
  uint256 amount;
  bytes32[] merkleProof;
}
```

#### multiClaim

```solidity
function multiClaim(address account, struct MultiMerkleDistributor.ClaimParams[] claims) external
```

Claims multiple rewards for a given list

*Calls the claim() method for each entry in the claims array*

**Parameters**

| Name    | Type                                         | Description                              |
| ------- | -------------------------------------------- | ---------------------------------------- |
| account | address                                      | Address of the user claiming the rewards |
| claims  | struct MultiMerkleDistributor.ClaimParams\[] | List of ClaimParams struct data to claim |

#### claimQuest

```solidity
function claimQuest(address account, uint256 questID, struct MultiMerkleDistributor.ClaimParams[] claims) external
```

Claims the reward for all the given periods of a Quest, and transfer all the rewards at once

*Sums up all the rewards for given periods of a Quest, and executes only one transfer*

**Parameters**

| Name    | Type                                         | Description                              |
| ------- | -------------------------------------------- | ---------------------------------------- |
| account | address                                      | Address of the user claiming the rewards |
| questID | uint256                                      | ID of the Quest                          |
| claims  | struct MultiMerkleDistributor.ClaimParams\[] | List of ClaimParams struct data to claim |

#### addQuest

```solidity
function addQuest(uint256 questID, address token) external returns (bool)
```

Adds a new Quest to the listing

*Adds a new Quest ID and the associated reward token*

**Parameters**

| Name    | Type    | Description                       |
| ------- | ------- | --------------------------------- |
| questID | uint256 | ID of the Quest                   |
| token   | address | Address of the ERC20 reward token |

**Return Values**

| Name | Type | Description    |
| ---- | ---- | -------------- |
| \[0] | bool | bool : success |

#### addQuestPeriod

```solidity
function addQuestPeriod(uint256 questID, uint256 period, uint256 totalRewardAmount) external returns (bool)
```

Adds a new period & the rewards of this period for a Quest

*Adds a new period & the rewards of this period for a Quest*

**Parameters**

| Name              | Type    | Description                                          |
| ----------------- | ------- | ---------------------------------------------------- |
| questID           | uint256 | ID of the Quest                                      |
| period            | uint256 | Timestamp of the period                              |
| totalRewardAmount | uint256 | Total amount of rewards to distribute for the period |

**Return Values**

| Name | Type | Description    |
| ---- | ---- | -------------- |
| \[0] | bool | bool : success |

#### fixQuestPeriod

```solidity
function fixQuestPeriod(uint256 questID, uint256 period, uint256 newTotalRewardAmount) external returns (bool)
```

#### updateQuestPeriod

```solidity
function updateQuestPeriod(uint256 questID, uint256 period, uint256 totalAmount, bytes32 merkleRoot) external returns (bool)
```

Updates the period of a Quest by adding the Merkle Root

*Add the Merkle Root for the eriod of the given Quest*

**Parameters**

| Name        | Type    | Description                            |
| ----------- | ------- | -------------------------------------- |
| questID     | uint256 | ID of the Quest                        |
| period      | uint256 | timestamp of the period                |
| totalAmount | uint256 | sum of all rewards for the Merkle Tree |
| merkleRoot  | bytes32 | MerkleRoot to add                      |

**Return Values**

| Name | Type | Description   |
| ---- | ---- | ------------- |
| \[0] | bool | bool: success |

#### recoverERC20

```solidity
function recoverERC20(address token) external returns (bool)
```

Recovers ERC2O tokens sent by mistake to the contract

*Recovers ERC2O tokens sent by mistake to the contract*

**Parameters**

| Name  | Type    | Description                |
| ----- | ------- | -------------------------- |
| token | address | Address tof the EC2O token |

**Return Values**

| Name | Type | Description   |
| ---- | ---- | ------------- |
| \[0] | bool | bool: success |

#### emergencyUpdateQuestPeriod

```solidity
function emergencyUpdateQuestPeriod(uint256 questID, uint256 period, uint256 addedRewardAmount, bytes32 merkleRoot) external returns (bool)
```

Allows to update the MerkleRoot for a given period of a Quest if the current Root is incorrect

*Updates the MerkleRoot for the period of the Quest*

**Parameters**

| Name              | Type    | Description             |
| ----------------- | ------- | ----------------------- |
| questID           | uint256 | ID of the Quest         |
| period            | uint256 | Timestamp of the period |
| addedRewardAmount | uint256 |                         |
| merkleRoot        | bytes32 | New MerkleRoot to add   |

**Return Values**

| Name | Type | Description    |
| ---- | ---- | -------------- |
| \[0] | bool | bool : success |
