# IMaverickV2IncentiveMatcher

### Functions <a href="#functions" id="functions"></a>

#### checkpointData <a href="#checkpointdata" id="checkpointdata"></a>

This function retrieves checkpoint data for a specific epoch.

```solidity
function checkpointData(uint256 epoch)
    external
    view
    returns (uint128 matchBudget, uint128 voteBudget, uint128 totalVote, uint128 totalExternalIncentivesAdded);
```

**Parameters**

| Name    | Type      | Description                                      |
| ------- | --------- | ------------------------------------------------ |
| `epoch` | `uint256` | The epoch for which to retrieve checkpoint data. |

**Returns**

| Name                           | Type      | Description                                                  |
| ------------------------------ | --------- | ------------------------------------------------------------ |
| `matchBudget`                  | `uint128` | The amount of match tokens budgeted for the epoch.           |
| `voteBudget`                   | `uint128` | The amount of vote tokens budgeted for the epoch.            |
| `totalVote`                    | `uint128` | The total number of votes cast in the epoch.                 |
| `totalExternalIncentivesAdded` | `uint128` | The total amount of external incentives added for the epoch. |

#### checkpointRewardData <a href="#checkpointrewarddata" id="checkpointrewarddata"></a>

This function retrieves checkpoint data for a specific reward contract within an epoch.

```solidity
function checkpointRewardData(uint256 epoch, IMaverickV2Reward rewardContract)
    external
    view
    returns (uint128 votesByReward, uint128 externalIncentivesByReward);
```

**Parameters**

| Name             | Type                | Description                                      |
| ---------------- | ------------------- | ------------------------------------------------ |
| `epoch`          | `uint256`           | The epoch for which to retrieve checkpoint data. |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract.              |

**Returns**

| Name                         | Type      | Description                                                                         |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------- |
| `votesByReward`              | `uint128` | The total number of votes cast for the reward contract in the epoch.                |
| `externalIncentivesByReward` | `uint128` | The total amount of external incentives added for the reward contract in the epoch. |

#### isEpoch <a href="#isepoch" id="isepoch"></a>

This function checks if a given epoch is valid.

```solidity
function isEpoch(uint256 epoch) external pure returns (bool _isEpoch);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                                |
| ---------- | ------ | ---------------------------------------------------------- |
| `_isEpoch` | `bool` | True if the epoch input is a valid epoch, False otherwise. |

#### lastEpoch <a href="#lastepoch" id="lastepoch"></a>

This function retrieves the number of the most recently completed epoch.

```solidity
function lastEpoch() external view returns (uint256 epoch);
```

**Returns**

| Name    | Type      | Description                   |
| ------- | --------- | ----------------------------- |
| `epoch` | `uint256` | The number of the last epoch. |

#### epochIsOver <a href="#epochisover" id="epochisover"></a>

This function checks if a specific epoch has ended.

```solidity
function epochIsOver(uint256 epoch) external view returns (bool isOver);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name     | Type   | Description                                   |
| -------- | ------ | --------------------------------------------- |
| `isOver` | `bool` | True if the epoch has ended, False otherwise. |

#### vetoingIsActive <a href="#vetoingisactive" id="vetoingisactive"></a>

This function checks if the vetoing period is active for a specific epoch.

```solidity
function vetoingIsActive(uint256 epoch) external view returns (bool isActive);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                            |
| ---------- | ------ | ------------------------------------------------------ |
| `isActive` | `bool` | True if the vetoing period is active, False otherwise. |

#### votingIsActive <a href="#votingisactive" id="votingisactive"></a>

This function checks if the voting period is active for a specific epoch.

```solidity
function votingIsActive(uint256 epoch) external view returns (bool isActive);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name       | Type   | Description                                           |
| ---------- | ------ | ----------------------------------------------------- |
| `isActive` | `bool` | True if the voting period is active, False otherwise. |

#### currentEpoch <a href="#currentepoch" id="currentepoch"></a>

This function retrieves the current epoch number.

```solidity
function currentEpoch() external view returns (uint256 epoch);
```

**Returns**

| Name    | Type      | Description               |
| ------- | --------- | ------------------------- |
| `epoch` | `uint256` | The current epoch number. |

#### votingStart <a href="#votingstart" id="votingstart"></a>

Returns the timestamp when voting starts. This is also the voting snapshot timestamp where the voting power for users is determined for that epoch.

```solidity
function votingStart(uint256 epoch) external pure returns (uint256 start);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

#### addMatchingBudget <a href="#addmatchingbudget" id="addmatchingbudget"></a>

This function allows adding a new budget to the matcher contract.

called by protocol to add base token budget to an epoch that will be used for matching incentives. Can be called anytime before or during the epoch.

```solidity
function addMatchingBudget(uint128 matchBudget, uint128 voteBudget, uint256 epoch) external;
```

**Parameters**

| Name          | Type      | Description                              |
| ------------- | --------- | ---------------------------------------- |
| `matchBudget` | `uint128` | The amount of match tokens to add.       |
| `voteBudget`  | `uint128` | The amount of vote tokens to add.        |
| `epoch`       | `uint256` | The epoch for which the budget is added. |

#### rewardHasVe <a href="#rewardhasve" id="rewardhasve"></a>

This function checks if a specific reward contract has a veToken staking option.

For a rewards contract to be eligible for matching, the rewards contract must have the baseToken's ve contract as a locking option.

```solidity
function rewardHasVe(IMaverickV2Reward rewardContract) external view returns (bool hasVe);
```

**Parameters**

| Name             | Type                | Description                         |
| ---------------- | ------------------- | ----------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract. |

**Returns**

| Name    | Type   | Description                                                                |
| ------- | ------ | -------------------------------------------------------------------------- |
| `hasVe` | `bool` | True if the reward contract has a veToken staking option, False otherwise. |

#### addIncentives <a href="#addincentives" id="addincentives"></a>

This function allows adding a new incentive to the system.

Called by protocol to add incentives to a given rewards contract.

```solidity
function addIncentives(IMaverickV2Reward rewardContract, uint256 amount, uint256 _duration)
    external
    returns (uint256 duration);
```

**Parameters**

| Name             | Type                | Description                                                       |
| ---------------- | ------------------- | ----------------------------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract for the incentive.             |
| `amount`         | `uint256`           | The total amount of the incentive.                                |
| `_duration`      | `uint256`           | The duration (in epochs) for which this incentive will be active. |

**Returns**

| Name       | Type      | Description                                                  |
| ---------- | --------- | ------------------------------------------------------------ |
| `duration` | `uint256` | The duration (in epochs) for which this incentive was added. |

#### vote <a href="#vote" id="vote"></a>

This function allows a user to cast a vote for specific reward contracts.

Called by ve token holders to vote for rewards contracts in a given epoch. voteTargets have to be passed in ascending sort order as a unique set of values. weights are relative values that are scales by the user's voting power.

```solidity
function vote(IMaverickV2Reward[] memory voteTargets, uint256[] memory weights) external;
```

**Parameters**

| Name          | Type                  | Description                                                 |
| ------------- | --------------------- | ----------------------------------------------------------- |
| `voteTargets` | `IMaverickV2Reward[]` | An array of addresses for the reward contracts to vote for. |
| `weights`     | `uint256[]`           | An array of weights for each vote target.                   |

#### veto <a href="#veto" id="veto"></a>

This function allows casting a veto on a specific reward contract for an epoch.

Veto a given rewards contract. If a rewards contract is vetoed, it will not receive any matching incentives. Rewards contracts can only be vetoed in the VETO\_PERIOD seconds after the end of the epoch.

```solidity
function veto(IMaverickV2Reward rewardContract) external returns (uint128 vetoPower);
```

**Parameters**

| Name             | Type                | Description                                 |
| ---------------- | ------------------- | ------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract to veto. |

**Returns**

| Name        | Type      | Description                                                                   |
| ----------- | --------- | ----------------------------------------------------------------------------- |
| `vetoPower` | `uint128` | The amount of veto power used (based on the user's epoch match contribution). |

#### distribute <a href="#distribute" id="distribute"></a>

This function allows distributing incentives for a specific reward contract in a particular epoch.

Called by any user to distribute matching incentives to a given reward contract for a given epoch. Call is only functional after the vetoing period for the epoch is over.

```solidity
function distribute(IMaverickV2Reward rewardContract, uint256 epoch) external returns (uint256 matchAmount);
```

**Parameters**

| Name             | Type                | Description                                                      |
| ---------------- | ------------------- | ---------------------------------------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract to distribute incentives for. |
| `epoch`          | `uint256`           | The epoch for which to distribute incentives.                    |

**Returns**

| Name          | Type      | Description                                |
| ------------- | --------- | ------------------------------------------ |
| `matchAmount` | `uint256` | The amount of matching tokens distributed. |

#### rolloverExcessBudget <a href="#rolloverexcessbudget" id="rolloverexcessbudget"></a>

This function allows rolling over excess budget from a previous epoch to a new epoch.

*Excess vote match budget amounts that have not been distributed will not rollover and will become permanently locked. To avoid this, a matcher should call distribute on all rewards contracts before calling rollover.*

```solidity
function rolloverExcessBudget(uint256 matchedEpoch, uint256 newEpoch)
    external
    returns (uint256 matchRolloverAmount, uint256 voteRolloverAmount);
```

**Parameters**

| Name           | Type      | Description                                   |
| -------------- | --------- | --------------------------------------------- |
| `matchedEpoch` | `uint256` | The epoch from which to roll over the budget. |
| `newEpoch`     | `uint256` | The epoch to which to roll over the budget.   |

**Returns**

| Name                  | Type      | Description                             |
| --------------------- | --------- | --------------------------------------- |
| `matchRolloverAmount` | `uint256` | The amount of match tokens rolled over. |
| `voteRolloverAmount`  | `uint256` | The amount of vote tokens rolled over.  |

#### EPOCH\_PERIOD <a href="#epoch_period" id="epoch_period"></a>

This function retrieves the epoch period length.

```solidity
function EPOCH_PERIOD() external returns (uint256);
```

#### PRE\_VOTE\_PERIOD <a href="#pre_vote_period" id="pre_vote_period"></a>

This function retrieves the period length of the epoch before voting starts. After an epoch begins, there is a window of time where voting is not possible which is the value this function returns.

```solidity
function PRE_VOTE_PERIOD() external returns (uint256);
```

#### VETO\_PERIOD <a href="#veto_period" id="veto_period"></a>

This function retrieves the vetoing period length.

```solidity
function VETO_PERIOD() external returns (uint256);
```

#### NOTIFY\_PERIOD <a href="#notify_period" id="notify_period"></a>

The function retrieves the notify period length, which is the amount of time in seconds during which the matching reward will be distributed through the rewards contract.

```solidity
function NOTIFY_PERIOD() external returns (uint256);
```

#### baseToken <a href="#basetoken" id="basetoken"></a>

This function retrieves the base token used by the IncentiveMatcher contract.

```solidity
function baseToken() external returns (IERC20);
```

**Returns**

| Name     | Type     | Description                    |
| -------- | -------- | ------------------------------ |
| `<none>` | `IERC20` | The address of the base token. |

#### factory <a href="#factory" id="factory"></a>

This function retrieves the address of the MaverickV2RewardFactory contract.

```solidity
function factory() external returns (IMaverickV2RewardFactory);
```

**Returns**

| Name     | Type                       | Description                                          |
| -------- | -------------------------- | ---------------------------------------------------- |
| `<none>` | `IMaverickV2RewardFactory` | The address of the MaverickV2RewardFactory contract. |

#### veToken <a href="#vetoken" id="vetoken"></a>

This function retrieves the address of the veToken contract.

```solidity
function veToken() external returns (IMaverickV2VotingEscrow);
```

**Returns**

| Name     | Type                      | Description                          |
| -------- | ------------------------- | ------------------------------------ |
| `<none>` | `IMaverickV2VotingEscrow` | The address of the veToken contract. |

#### hasVoted <a href="#hasvoted" id="hasvoted"></a>

This function checks if a specific user has voted in a particular epoch.

```solidity
function hasVoted(address user, uint256 epoch) external returns (bool);
```

**Parameters**

| Name    | Type      | Description              |
| ------- | --------- | ------------------------ |
| `user`  | `address` | The address of the user. |
| `epoch` | `uint256` | The epoch to check.      |

**Returns**

| Name     | Type   | Description                                  |
| -------- | ------ | -------------------------------------------- |
| `<none>` | `bool` | True if the user has voted, False otherwise. |

#### hasVetoed <a href="#hasvetoed" id="hasvetoed"></a>

This function checks if a specific matcher has cast a veto on a reward contract for an epoch.

```solidity
function hasVetoed(address matcher, IMaverickV2Reward rewardContract, uint256 epoch) external returns (bool);
```

**Parameters**

| Name             | Type                | Description                                   |
| ---------------- | ------------------- | --------------------------------------------- |
| `matcher`        | `address`           | The address of the IncentiveMatcher contract. |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract.           |
| `epoch`          | `uint256`           | The epoch to check.                           |

**Returns**

| Name     | Type   | Description                                           |
| -------- | ------ | ----------------------------------------------------- |
| `<none>` | `bool` | True if the matcher has cast a veto, False otherwise. |

#### hasDistributed <a href="#hasdistributed" id="hasdistributed"></a>

This function checks if incentives have been distributed for a specific reward contract in an epoch.

```solidity
function hasDistributed(IMaverickV2Reward rewardContract, uint256 epoch) external returns (bool);
```

**Parameters**

| Name             | Type                | Description                         |
| ---------------- | ------------------- | ----------------------------------- |
| `rewardContract` | `IMaverickV2Reward` | The address of the reward contract. |
| `epoch`          | `uint256`           | The epoch to check.                 |

**Returns**

| Name     | Type   | Description                                                |
| -------- | ------ | ---------------------------------------------------------- |
| `<none>` | `bool` | True if incentives have been distributed, False otherwise. |

#### epochEnd <a href="#epochend" id="epochend"></a>

This function calculates the end timestamp for a specific epoch.

```solidity
function epochEnd(uint256 epoch) external pure returns (uint256 end);
```

**Parameters**

| Name    | Type      | Description                                         |
| ------- | --------- | --------------------------------------------------- |
| `epoch` | `uint256` | The epoch for which to calculate the end timestamp. |

**Returns**

| Name  | Type      | Description                     |
| ----- | --------- | ------------------------------- |
| `end` | `uint256` | The end timestamp of the epoch. |

#### vetoingEnd <a href="#vetoingend" id="vetoingend"></a>

This function calculates the end timestamp for the vetoing period of a specific epoch.

```solidity
function vetoingEnd(uint256 epoch) external pure returns (uint256 end);
```

**Parameters**

| Name    | Type      | Description                                                        |
| ------- | --------- | ------------------------------------------------------------------ |
| `epoch` | `uint256` | The epoch for which to calculate the vetoing period end timestamp. |

**Returns**

| Name  | Type      | Description                                            |
| ----- | --------- | ------------------------------------------------------ |
| `end` | `uint256` | The end timestamp of the vetoing period for the epoch. |

#### vetoingIsOver <a href="#vetoingisover" id="vetoingisover"></a>

This function checks if the vetoing period is over for a specific epoch.

```solidity
function vetoingIsOver(uint256 epoch) external view returns (bool isOver);
```

**Parameters**

| Name    | Type      | Description         |
| ------- | --------- | ------------------- |
| `epoch` | `uint256` | The epoch to check. |

**Returns**

| Name     | Type   | Description                                                                |
| -------- | ------ | -------------------------------------------------------------------------- |
| `isOver` | `bool` | True if the vetoing period has ended for the given epoch, False otherwise. |

### Events <a href="#events" id="events"></a>

#### BudgetAdded <a href="#budgetadded" id="budgetadded"></a>

```solidity
event BudgetAdded(address matcher, uint256 matchRolloverAmount, uint256 voteRolloverAmount, uint256 epoch);
```

#### BudgetRolledOver <a href="#budgetrolledover" id="budgetrolledover"></a>

```solidity
event BudgetRolledOver(
    address matcher, uint256 matchRolloverAmount, uint256 voteRolloverAmount, uint256 matchedEpoch, uint256 newEpoch
);
```

#### IncentiveAdded <a href="#incentiveadded" id="incentiveadded"></a>

```solidity
event IncentiveAdded(uint256 amount, uint256 epoch, IMaverickV2Reward rewardContract, uint256 duration);
```

#### Vote <a href="#vote-1" id="vote-1"></a>

```solidity
event Vote(address voter, uint256 epoch, IMaverickV2Reward rewardContract, uint256 vote);
```

#### Distribute <a href="#distribute-1" id="distribute-1"></a>

```solidity
event Distribute(uint256 epoch, IMaverickV2Reward rewardContract, IERC20 _baseToken, uint256 matchAmount);
```

#### Veto <a href="#veto-1" id="veto-1"></a>

```solidity
event Veto(address matcher, uint256 epoch, IMaverickV2Reward rewardContract, uint256 amount, uint256 vetoPower);
```

### Errors <a href="#errors" id="errors"></a>

#### IncentiveMatcherInvalidEpoch <a href="#incentivematcherinvalidepoch" id="incentivematcherinvalidepoch"></a>

```solidity
error IncentiveMatcherInvalidEpoch(uint256 epoch);
```

#### IncentiveMatcherNotRewardFactoryContract <a href="#incentivematchernotrewardfactorycontract" id="incentivematchernotrewardfactorycontract"></a>

```solidity
error IncentiveMatcherNotRewardFactoryContract(IMaverickV2Reward rewardContract);
```

#### IncentiveMatcherEpochHasNotEnded <a href="#incentivematcherepochhasnotended" id="incentivematcherepochhasnotended"></a>

```solidity
error IncentiveMatcherEpochHasNotEnded(uint256 currentTime, uint256 epochEnd);
```

#### IncentiveMatcherVotePeriodNotActive <a href="#incentivematchervoteperiodnotactive" id="incentivematchervoteperiodnotactive"></a>

```solidity
error IncentiveMatcherVotePeriodNotActive(uint256 currentTime, uint256 voteStart, uint256 voteEnd);
```

#### IncentiveMatcherVetoPeriodNotActive <a href="#incentivematchervetoperiodnotactive" id="incentivematchervetoperiodnotactive"></a>

```solidity
error IncentiveMatcherVetoPeriodNotActive(uint256 currentTime, uint256 vetoStart, uint256 vetoEnd);
```

#### IncentiveMatcherVetoPeriodHasNotEnded <a href="#incentivematchervetoperiodhasnotended" id="incentivematchervetoperiodhasnotended"></a>

```solidity
error IncentiveMatcherVetoPeriodHasNotEnded(uint256 currentTime, uint256 voteEnd);
```

#### IncentiveMatcherSenderHasAlreadyVoted <a href="#incentivematchersenderhasalreadyvoted" id="incentivematchersenderhasalreadyvoted"></a>

```solidity
error IncentiveMatcherSenderHasAlreadyVoted();
```

#### IncentiveMatcherSenderHasNoVotingPower <a href="#incentivematchersenderhasnovotingpower" id="incentivematchersenderhasnovotingpower"></a>

```solidity
error IncentiveMatcherSenderHasNoVotingPower(address voter, uint256 voteSnapshotTimestamp);
```

#### IncentiveMatcherInvalidTargetOrder <a href="#incentivematcherinvalidtargetorder" id="incentivematcherinvalidtargetorder"></a>

```solidity
error IncentiveMatcherInvalidTargetOrder(IMaverickV2Reward lastReward, IMaverickV2Reward voteReward);
```

#### IncentiveMatcherInvalidVote <a href="#incentivematcherinvalidvote" id="incentivematcherinvalidvote"></a>

```solidity
error IncentiveMatcherInvalidVote(
    IMaverickV2Reward rewardContract, uint256 voteWeights, uint256 totalVoteWeight, uint256 vote
);
```

#### IncentiveMatcherNoExternalIncentivesToDistributed <a href="#incentivematchernoexternalincentivestodistributed" id="incentivematchernoexternalincentivestodistributed"></a>

```solidity
error IncentiveMatcherNoExternalIncentivesToDistributed(IMaverickV2Reward rewardContract, uint256 epoch);
```

#### IncentiveMatcherEpochAlreadyDistributed <a href="#incentivematcherepochalreadydistributed" id="incentivematcherepochalreadydistributed"></a>

```solidity
error IncentiveMatcherEpochAlreadyDistributed(uint256 epoch, IMaverickV2Reward rewardContract);
```

#### IncentiveMatcherEpochHasPassed <a href="#incentivematcherepochhaspassed" id="incentivematcherepochhaspassed"></a>

```solidity
error IncentiveMatcherEpochHasPassed(uint256 epoch);
```

#### IncentiveMatcherRewardDoesNotHaveVeStakingOption <a href="#incentivematcherrewarddoesnothavevestakingoption" id="incentivematcherrewarddoesnothavevestakingoption"></a>

```solidity
error IncentiveMatcherRewardDoesNotHaveVeStakingOption();
```

#### IncentiveMatcherMatcherAlreadyVetoed <a href="#incentivematchermatcheralreadyvetoed" id="incentivematchermatcheralreadyvetoed"></a>

```solidity
error IncentiveMatcherMatcherAlreadyVetoed(address matcher, IMaverickV2Reward rewardContract, uint256 epoch);
```

#### IncentiveMatcherNothingToRollover <a href="#incentivematchernothingtorollover" id="incentivematchernothingtorollover"></a>

```solidity
error IncentiveMatcherNothingToRollover(address matcher, uint256 matchedEpoch);
```
