# QuestBoard

The QuestBoard is the main smart contract of Warden Quest. This smart contract lists all the past and active Quests, allows to create Quest and increase Quest parameters, calculates Quest efficiency percentage at the end of each period, and transfers the correct amount of rewards to be distributed to the Distributor smart contract.

## Structs

### Quest

Struct holding the parameters of the Quest common for all periods

`struct Quest {` \
`// Address of the Quest creator (caller of createQuest() method)` \
`address creator;` \
`// Address of the ERC20 used for rewards` \
`address rewardToken;` \
`// Address of the target Gauge` \
`address gauge;` \
`// Total number of periods for the Quest` \
`uint48 duration;` \
`// Timestamp where the 1st QuestPeriod starts` \
`uint48 periodStart;` \
`// Total amount of rewards paid for this Quest` \
`// If changes were made to the parameters of this Quest, this will account` \
`// any added reward amounts` \
`uint256 totalRewardAmount;` \
`}`

### QuestPeriod

Struct for a Period of a Quest

`struct QuestPeriod {` \
`// Total reward amount that can be distributed for that period` \
`uint256 rewardAmountPerPeriod;` \
`// Amount of reward for each vote (for 1 veCRV)` \
`uint256 rewardPerVote;` \
`// Tartget Bias for the Gauge` \
`uint256 objectiveVotes;` \
`// Amount of reward to distribute, at period closing` \
`uint256 rewardAmountDistributed;` \
`// Amount not distributed, for Quest creator to redeem` \
`uint256 withdrawableAmount;` \
`// Timestamp of the Period start` \
`uint48 periodStart;` \
`// Current state of the Period` \
`PeriodState currentState;` \
`}`

With `PeriodState` is the enum:

`enum PeriodState { ZERO, ACTIVE, CLOSED, DISTRIBUTED }`&#x20;

All Periods are `ACTIVE` at creation since the voters from past periods are also accounted for the future period

Periods: timestamp => start of a week, used as a voting period in the Curve GaugeController though `the timestamp / WEEK * WEEK` logic.

## Storage mappings & variables

### quests

All Quests (indexed by ID)

`mapping(uint256 => Quest) public quests;`

### questPeriods

Timestamp periods the Quest is active in

`mapping(uint256 => uint48[]) public questPeriods;`

### periodsByQuest

Mapping of all QuestPeriod struct for each period of each Quest

QuestID => period => QuestPeriod&#x20;

`mapping(uint256 => mapping(uint256 => QuestPeriod)) public periodsByQuest;`

### questsByPeriod

All the Quests active during this period

`mapping(uint256 => uint256[]) public questsByPeriod;`

### questDistributors

Mapping of Distributors used by each Quest to send rewards

`mapping(uint256 => address) public questDistributors;`

### whitelistedTokens

Whitelisted tokens that can be used as reward tokens

`mapping(address => bool) public whitelistedTokens;`

### minRewardPerVotePerToken

Minimum rewardPerVote per token (to avoid spam creation of useless Quest)

`mapping(address => uint256) public minRewardPerVotePerToken;`

### platformFee

Platform fees ratio (in BPS)

`uint256 public platformFee = 500;`

### minObjective

Minimum Objective required

`uint256 public minObjective;`

### questChest

Address of the Chest to receive platform fees

`address public questChest;`

### distributor

Address of the reward Distributor contract&#x20;

`address public distributor;`

## Read only methods

### getCurrentPeriod

Returns the current Period for the contract

`function getCurrentPeriod() public view returns(uint256)`

### getQuestIdsForPeriod

Returns the list of all Quest IDs active on a given period

`function getQuestIdsForPeriod(uint256 period) external view returns(uint256[] memory)`

### getAllPeriodsForQuestId

Returns all periods for a Quest

`function getAllPeriodsForQuestId(uint256 questId) external view returns(uint48[] memory)`

### getAllPeriodsForQuestId

Returns all QuestPeriod of a given Quest

`function getAllQuestPeriodsForQuestId(uint256 questId) external view returns(QuestPeriod[] memory)`

## User state-changing functions

### createQuest

Creates a new Quest

`function createQuest( address gauge, address rewardToken, uint48 duration, uint256 objective, uint256 rewardPerVote, uint256 totalRewardAmount, uint256 feeAmount ) external returns(uint256)`

**Parameters:**

* `gauge` Address of the Gauge targeted by the Quest
* `rewardToken` Address of the reward token
* `duration` Duration (in number of periods) of the Quest
* `objective` Target bias to reach (equivalent to amount of veCRV in wei to reach)
* `rewardPerVote` Amount of reward per veCRV (in wei)
* `totalRewardAmount` Total amount of rewards for the whole Quest (in wei)
* `feeAmount` Platform fees amount (in wei)

Returns: `uint256` : ID of the newly created Quest

### increaseQuestDuration

Increases the duration of a Quest

`function increaseQuestDuration( uint256 questID, uint48 addedDuration, uint256 addedRewardAmount, uint256 feeAmount ) external`

**Parameters:**

* `questID` ID of the Quest&#x20;
* `addedDuration` Number of period to add&#x20;
* `addedRewardAmount` Amount of reward to add for the new periods (in wei)&#x20;
* `feeAmount` Platform fees amount (in wei)

### increaseQuestReward

Increases the reward per votes for a Quest

`function increaseQuestReward( uint256 questID, uint256 newRewardPerVote, uint256 addedRewardAmount, uint256 feeAmount ) external`

**Parameters:**

* `questID` ID of the Quest&#x20;
* `newRewardPerVote` New amount of reward per veCRV (in wei)&#x20;
* `addedRewardAmount` Amount of rewards to add (in wei)&#x20;
* `feeAmount` Platform fees amount (in wei)

### increaseQuestObjective

Increases the target bias/veCRV amount to reach on the Gauge

`function increaseQuestObjective( uint256 questID, uint256 newObjective, uint256 addedRewardAmount, uint256 feeAmount ) external`

**Parameters:**

* `questID` ID of the Quest
* `newObjective` New target bias to reach (equivalent to amount of veCRV in wei to reach)
* `addedRewardAmount` Amount of rewards to add (in wei)
* `feeAmount` Platform fees amount (in wei)

### withdrawUnusedRewards

Withdraw all undistributed rewards from Closed Quest Periods

`function withdrawUnusedRewards(uint256 questID, address recipient) external`


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.paladin.vote/warden-quest-v1-deprecated/smart-contracts/questboard.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
