# IMaverickV2VotingEscrowBase

**Inherits:** IVotes, [IHistoricalBalance](https://docs.mav.xyz/technical-reference/maverick-v2/v2-contracts/maverick-v2-reward-contracts/votingescrowbase/ihistoricalbalance)

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

#### MIN\_STAKE\_DURATION <a href="#min_stake_duration" id="min_stake_duration"></a>

```solidity
function MIN_STAKE_DURATION() external returns (uint256 duration);
```

#### MAX\_STAKE\_DURATION <a href="#max_stake_duration" id="max_stake_duration"></a>

```solidity
function MAX_STAKE_DURATION() external returns (uint256 duration);
```

#### YEAR\_BASE <a href="#year_base" id="year_base"></a>

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

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

This function retrieves the address of the ERC20 token used as the base token for staking and rewards.

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

**Returns**

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

#### startTimestamp <a href="#starttimestamp" id="starttimestamp"></a>

This function retrieves the starting timestamp. This may be used for reward calculations or other time-based logic.

```solidity
function startTimestamp() external returns (uint256 timestamp);
```

#### getLockup <a href="#getlockup" id="getlockup"></a>

This function retrieves the details of a specific lockup for a given staker and lockup index.

```solidity
function getLockup(address staker, uint256 index) external view returns (Lockup memory lockup);
```

**Parameters**

| Name     | Type      | Description                                                         |
| -------- | --------- | ------------------------------------------------------------------- |
| `staker` | `address` | The address of the staker for which to retrieve the lockup details. |
| `index`  | `uint256` | The index of the lockup within the staker's lockup history.         |

**Returns**

| Name     | Type     | Description                                                                              |
| -------- | -------- | ---------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the lockup (see struct definition for details). |

#### lockupCount <a href="#lockupcount" id="lockupcount"></a>

This function retrieves the total number of lockups associated with a specific staker.

```solidity
function lockupCount(address staker) external view returns (uint256 count);
```

**Parameters**

| Name     | Type      | Description                                                       |
| -------- | --------- | ----------------------------------------------------------------- |
| `staker` | `address` | The address of the staker for which to retrieve the lockup count. |

**Returns**

| Name    | Type      | Description                                 |
| ------- | --------- | ------------------------------------------- |
| `count` | `uint256` | The total number of lockups for the staker. |

#### previewVotes <a href="#previewvotes" id="previewvotes"></a>

This function simulates a lockup scenario, providing details about the resulting lockup structure for a specified amount and duration.

```solidity
function previewVotes(uint128 amount, uint256 duration) external view returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                        |
| ---------- | --------- | ---------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be locked. |
| `duration` | `uint256` | The duration of the lockup period. |

**Returns**

| Name     | Type     | Description                                                                                        |
| -------- | -------- | -------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the simulated lockup (see struct definition for details). |

#### approveExtender <a href="#approveextender" id="approveextender"></a>

This function grants approval for a designated extender contract to manage a specific lockup on behalf of the staker.

```solidity
function approveExtender(address extender, uint256 lockupId) external;
```

**Parameters**

| Name       | Type      | Description                                          |
| ---------- | --------- | ---------------------------------------------------- |
| `extender` | `address` | The address of the extender contract to be approved. |
| `lockupId` | `uint256` | The ID of the lockup for which to grant approval.    |

#### revokeExtender <a href="#revokeextender" id="revokeextender"></a>

This function revokes approval previously granted to an extender contract for managing a specific lockup.

```solidity
function revokeExtender(address extender, uint256 lockupId) external;
```

**Parameters**

| Name       | Type      | Description                                                           |
| ---------- | --------- | --------------------------------------------------------------------- |
| `extender` | `address` | The address of the extender contract whose approval is being revoked. |
| `lockupId` | `uint256` | The ID of the lockup for which to revoke approval.                    |

#### isApprovedExtender <a href="#isapprovedextender" id="isapprovedextender"></a>

This function checks whether a specific account has been approved by a staker to manage a particular lockup through an extender contract.

```solidity
function isApprovedExtender(address account, address extender, uint256 lockupId) external view returns (bool);
```

**Parameters**

| Name       | Type      | Description                                                                                |
| ---------- | --------- | ------------------------------------------------------------------------------------------ |
| `account`  | `address` | The address of the account to check for approval (may be the extender or another account). |
| `extender` | `address` | The address of the extender contract for which to check approval.                          |
| `lockupId` | `uint256` | The ID of the lockup to verify approval for.                                               |

**Returns**

| Name     | Type   | Description                                                                        |
| -------- | ------ | ---------------------------------------------------------------------------------- |
| `<none>` | `bool` | isApproved True if the account is approved for the lockup, False otherwise (bool). |

#### extendForSender <a href="#extendforsender" id="extendforsender"></a>

This function extends the lockup period for the caller (msg.sender) for a specified lockup ID, adding a new duration and amount.

```solidity
function extendForSender(uint256 lockupId, uint256 duration, uint128 amount)
    external
    returns (Lockup memory newLockup);
```

**Parameters**

| Name       | Type      | Description                                      |
| ---------- | --------- | ------------------------------------------------ |
| `lockupId` | `uint256` | The ID of the lockup to be extended.             |
| `duration` | `uint256` | The additional duration to extend the lockup by. |
| `amount`   | `uint128` | The additional amount of tokens to be locked.    |

**Returns**

| Name        | Type     | Description                                                                                             |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly extended lockup (see struct definition for details). |

#### extendForAccount <a href="#extendforaccount" id="extendforaccount"></a>

This function extends the lockup period for a specified account, adding a new duration and amount. The caller (msg.sender) must be authorized to manage the lockup through an extender contract.

```solidity
function extendForAccount(address account, uint256 lockupId, uint256 duration, uint128 amount)
    external
    returns (Lockup memory newLockup);
```

**Parameters**

| Name       | Type      | Description                                                |
| ---------- | --------- | ---------------------------------------------------------- |
| `account`  | `address` | The address of the account whose lockup is being extended. |
| `lockupId` | `uint256` | The ID of the lockup to be extended.                       |
| `duration` | `uint256` | The additional duration to extend the lockup by.           |
| `amount`   | `uint128` | The additional amount of tokens to be locked.              |

**Returns**

| Name        | Type     | Description                                                                                             |
| ----------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly extended lockup (see struct definition for details). |

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

This function merges multiple lockups associated with the caller (msg.sender) into a single new lockup.

```solidity
function merge(uint256[] memory lockupIds) external returns (Lockup memory newLockup);
```

**Parameters**

| Name        | Type        | Description                                              |
| ----------- | ----------- | -------------------------------------------------------- |
| `lockupIds` | `uint256[]` | An array containing the IDs of the lockups to be merged. |

**Returns**

| Name        | Type     | Description                                                                                           |
| ----------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `newLockup` | `Lockup` | A Lockup struct containing details about the newly merged lockup (see struct definition for details). |

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

This function unstakes the specified lockup ID for the caller (msg.sender), returning the details of the unstaked lockup.

```solidity
function unstake(uint256 lockupId, address to) external returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                                                                                 |
| ---------- | --------- | ------------------------------------------------------------------------------------------- |
| `lockupId` | `uint256` | The ID of the lockup to be unstaked.                                                        |
| `to`       | `address` | The address to which the unstaked tokens should be sent (optional, defaults to msg.sender). |

**Returns**

| Name     | Type     | Description                                                                                       |
| -------- | -------- | ------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the unstaked lockup (see struct definition for details). |

#### unstakeToSender <a href="#unstaketosender" id="unstaketosender"></a>

This function is a simplified version of `unstake` that automatically sends the unstaked tokens to the caller (msg.sender).

```solidity
function unstakeToSender(uint256 lockupId) external returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                          |
| ---------- | --------- | ------------------------------------ |
| `lockupId` | `uint256` | The ID of the lockup to be unstaked. |

**Returns**

| Name     | Type     | Description                                                                                       |
| -------- | -------- | ------------------------------------------------------------------------------------------------- |
| `lockup` | `Lockup` | A Lockup struct containing details about the unstaked lockup (see struct definition for details). |

#### stakeToSender <a href="#staketosender" id="staketosender"></a>

This function stakes a specified amount of tokens for the caller (msg.sender) for a defined duration.

```solidity
function stakeToSender(uint128 amount, uint256 duration) external returns (Lockup memory lockup);
```

**Parameters**

| Name       | Type      | Description                        |
| ---------- | --------- | ---------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be staked. |
| `duration` | `uint256` | The duration of the lockup period. |

**Returns**

| Name     | Type     | Description                                                                                            |
| -------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `lockup` | `Lockup` | A Lockup struct containing details about the newly created lockup (see struct definition for details). |

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

This function stakes a specified amount of tokens for a defined duration, allowing the caller (msg.sender) to specify an optional recipient for the staked tokens.

```solidity
function stake(uint128 amount, uint256 duration, address to) external returns (Lockup memory);
```

**Parameters**

| Name       | Type      | Description                                                                                 |
| ---------- | --------- | ------------------------------------------------------------------------------------------- |
| `amount`   | `uint128` | The amount of tokens to be staked.                                                          |
| `duration` | `uint256` | The duration of the lockup period.                                                          |
| `to`       | `address` | The address to which the staked tokens will be credited (optional, defaults to msg.sender). |

**Returns**

| Name     | Type     | Description                                                                                                   |
| -------- | -------- | ------------------------------------------------------------------------------------------------------------- |
| `<none>` | `Lockup` | lockup A Lockup struct containing details about the newly created lockup (see struct definition for details). |

#### incentiveTotals <a href="#incentivetotals" id="incentivetotals"></a>

This function retrieves the total incentive information for a specific ERC-20 token.

```solidity
function incentiveTotals(IERC20 token) external view returns (TokenIncentiveTotals memory);
```

**Parameters**

| Name    | Type     | Description                                                            |
| ------- | -------- | ---------------------------------------------------------------------- |
| `token` | `IERC20` | The address of the ERC20 token for which to retrieve incentive totals. |

**Returns**

| Name     | Type                   | Description                                                                                                               |
| -------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `<none>` | `TokenIncentiveTotals` | totals A TokenIncentiveTotals struct containing details about the token's incentives (see struct definition for details). |

#### incentiveBatchCount <a href="#incentivebatchcount" id="incentivebatchcount"></a>

This function retrieves the total number of created incentive batches.

```solidity
function incentiveBatchCount() external view returns (uint256);
```

**Returns**

| Name     | Type      | Description                                  |
| -------- | --------- | -------------------------------------------- |
| `<none>` | `uint256` | count The total number of incentive batches. |

#### claimInformation <a href="#claiminformation" id="claiminformation"></a>

This function retrieves claim information for a specific account and incentive batch index.

```solidity
function claimInformation(address account, uint256 batchIndex) external view returns (ClaimInformation memory info);
```

**Parameters**

| Name         | Type      | Description                                                               |
| ------------ | --------- | ------------------------------------------------------------------------- |
| `account`    | `address` | The address of the account for which to retrieve claim information.       |
| `batchIndex` | `uint256` | The index of the incentive batch for which to retrieve claim information. |

**Returns**

| Name   | Type               | Description                                                                                                                          |
| ------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `info` | `ClaimInformation` | A ClaimInformation struct containing details about the account's claims for the specified batch (see struct definition for details). |

#### claimFromIncentiveBatchAndExtend <a href="#claimfromincentivebatchandextend" id="claimfromincentivebatchandextend"></a>

This function allows claiming rewards from a specific incentive batch while simultaneously extending a lockup with the claimed tokens.

```solidity
function claimFromIncentiveBatchAndExtend(uint256 batchIndex, uint256 lockupId)
    external
    returns (Lockup memory lockup, uint128 claimAmount);
```

**Parameters**

| Name         | Type      | Description                                                   |
| ------------ | --------- | ------------------------------------------------------------- |
| `batchIndex` | `uint256` | The index of the incentive batch from which to claim rewards. |
| `lockupId`   | `uint256` | The ID of the lockup to be extended with the claimed tokens.  |

**Returns**

| Name          | Type      | Description                                                                                                      |
| ------------- | --------- | ---------------------------------------------------------------------------------------------------------------- |
| `lockup`      | `Lockup`  | A Lockup struct containing details about the updated lockup after extension (see struct definition for details). |
| `claimAmount` | `uint128` | The amount of tokens claimed from the incentive batch.                                                           |

#### claimFromIncentiveBatch <a href="#claimfromincentivebatch" id="claimfromincentivebatch"></a>

This function allows claiming rewards from a specific incentive batch, without extending any lockups.

```solidity
function claimFromIncentiveBatch(uint256 batchIndex) external returns (Lockup memory lockup, uint128 claimAmount);
```

**Parameters**

| Name         | Type      | Description                                                   |
| ------------ | --------- | ------------------------------------------------------------- |
| `batchIndex` | `uint256` | The index of the incentive batch from which to claim rewards. |

**Returns**

| Name          | Type      | Description                                                                                                                                |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `lockup`      | `Lockup`  | A Lockup struct containing details about the user's lockup that might have been affected by the claim (see struct definition for details). |
| `claimAmount` | `uint128` | The amount of tokens claimed from the incentive batch.                                                                                     |

#### createIncentiveBatch <a href="#createincentivebatch" id="createincentivebatch"></a>

This function creates a new incentive batch for a specified amount of incentive tokens, timepoint, stake duration, and associated ERC-20 token. An incentive batch is a reward of incentives put up by the caller at a certain timepoint. The incentive batch is claimable by ve holders after the timepoint has passed. The ve holders will receive their incentive pro rata of their vote balance (`pastbalanceOf`) at that timepoint. The incentivizer can specify that users have to stake the resulting incentive for a given `stakeDuration` number of seconds. `stakeDuration` can either be zero, meaning that no staking is required on redemption, or can be a number between `MIN_STAKE_DURATION()` and `MAX_STAKE_DURATION()`.

```solidity
function createIncentiveBatch(uint128 amount, uint48 timepoint, uint128 stakeDuration, IERC20 incentiveToken)
    external
    returns (uint256 index);
```

**Parameters**

| Name             | Type      | Description                                                                                |
| ---------------- | --------- | ------------------------------------------------------------------------------------------ |
| `amount`         | `uint128` | The total amount of incentive tokens to be distributed in the batch.                       |
| `timepoint`      | `uint48`  | The timepoint at which the incentive batch starts accruing rewards.                        |
| `stakeDuration`  | `uint128` | The duration of the lockup period required to be eligible for the incentive batch rewards. |
| `incentiveToken` | `IERC20`  | The address of the ERC20 token used for the incentive rewards.                             |

**Returns**

| Name    | Type      | Description                                     |
| ------- | --------- | ----------------------------------------------- |
| `index` | `uint256` | The index of the newly created incentive batch. |

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

#### Stake <a href="#stake-1" id="stake-1"></a>

```solidity
event Stake(address indexed user, uint256 lockupId, Lockup);
```

#### Unstake <a href="#unstake-1" id="unstake-1"></a>

```solidity
event Unstake(address indexed user, uint256 lockupId, Lockup);
```

#### ExtenderApproval <a href="#extenderapproval" id="extenderapproval"></a>

```solidity
event ExtenderApproval(address staker, address extender, uint256 lockupId, bool newState);
```

#### ClaimIncentiveBatch <a href="#claimincentivebatch" id="claimincentivebatch"></a>

```solidity
event ClaimIncentiveBatch(uint256 batchIndex, address account, uint256 claimAmount);
```

#### CreateNewIncentiveBatch <a href="#createnewincentivebatch" id="createnewincentivebatch"></a>

```solidity
event CreateNewIncentiveBatch(
    address user, uint256 amount, uint256 timepoint, uint256 stakeDuration, IERC20 incentiveToken
);
```

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

#### VotingEscrowTransferNotSupported <a href="#votingescrowtransfernotsupported" id="votingescrowtransfernotsupported"></a>

```solidity
error VotingEscrowTransferNotSupported();
```

#### VotingEscrowInvalidAddress <a href="#votingescrowinvalidaddress" id="votingescrowinvalidaddress"></a>

```solidity
error VotingEscrowInvalidAddress(address);
```

#### VotingEscrowInvalidAmount <a href="#votingescrowinvalidamount" id="votingescrowinvalidamount"></a>

```solidity
error VotingEscrowInvalidAmount(uint256);
```

#### VotingEscrowInvalidDuration <a href="#votingescrowinvalidduration" id="votingescrowinvalidduration"></a>

```solidity
error VotingEscrowInvalidDuration(uint256 duration, uint256 minDuration, uint256 maxDuration);
```

#### VotingEscrowInvalidEndTime <a href="#votingescrowinvalidendtime" id="votingescrowinvalidendtime"></a>

```solidity
error VotingEscrowInvalidEndTime(uint256 newEnd, uint256 oldEnd);
```

#### VotingEscrowStakeStillLocked <a href="#votingescrowstakestilllocked" id="votingescrowstakestilllocked"></a>

```solidity
error VotingEscrowStakeStillLocked(uint256 currentTime, uint256 endTime);
```

#### VotingEscrowStakeAlreadRedeemed <a href="#votingescrowstakealreadredeemed" id="votingescrowstakealreadredeemed"></a>

```solidity
error VotingEscrowStakeAlreadRedeemed();
```

#### VotingEscrowNotApprovedExtender <a href="#votingescrownotapprovedextender" id="votingescrownotapprovedextender"></a>

```solidity
error VotingEscrowNotApprovedExtender(address account, address extender, uint256 lockupId);
```

#### VotingEscrowIncentiveAlreadyClaimed <a href="#votingescrowincentivealreadyclaimed" id="votingescrowincentivealreadyclaimed"></a>

```solidity
error VotingEscrowIncentiveAlreadyClaimed(address account, uint256 batchIndex);
```

#### VotingEscrowNoIncentivesToClaim <a href="#votingescrownoincentivestoclaim" id="votingescrownoincentivestoclaim"></a>

```solidity
error VotingEscrowNoIncentivesToClaim(address account, uint256 batchIndex);
```

#### VotingEscrowInvalidExtendIncentiveToken <a href="#votingescrowinvalidextendincentivetoken" id="votingescrowinvalidextendincentivetoken"></a>

```solidity
error VotingEscrowInvalidExtendIncentiveToken(IERC20 incentiveToken);
```

### Structs <a href="#structs" id="structs"></a>

#### Lockup <a href="#lockup" id="lockup"></a>

```solidity
struct Lockup {
    uint128 amount;
    uint128 end;
    uint256 votes;
}
```

#### ClaimInformation <a href="#claiminformation-1" id="claiminformation-1"></a>

```solidity
struct ClaimInformation {
    bool hasClaimed;
    uint128 claimAmount;
    uint256 stakeDuration;
    IERC20 incentiveToken;
}
```

#### TokenIncentiveTotals <a href="#tokenincentivetotals" id="tokenincentivetotals"></a>

```solidity
struct TokenIncentiveTotals {
    uint128 totalIncentives;
    uint128 claimedIncentives;
}
```
