# Voter



## Overview [#overview]

The `Voter` contract records pool voting weights for veNFTs and creates and claims pool voting rewards. A position is identified by its vote-escrow contract address (`_ve`) and NFT identifier (`_tokenId`). Voting power is obtained through the governance registry's voting-escrow aggregator, which applies the registered weight of each escrow.

<Callout type="info">
  Gauge voting and the voting-incentives marketplace are paused under [SGP-20](https://paragraph.com/@spectra/sgp-20-is-now-in-effect-spectra-emissions-reduced-to-zero). Weekly emissions and the rebase are zero. [SGP-19](https://snapshot.box/#/s:spectradao.eth/proposal/0xd1a081c2783ba428627fbafa2a65d9d26571eae45647917d45bd7571d18a493b) routes the pool swap-fee share allocated through the ve(3,3) path to the DAO treasury. Protocol proposal voting remains active; see the [governance guide](/docs/guides/voting-and-earning-rewards).
</Callout>

Pool IDs are `uint160` identifiers that distinguish pools across networks. Obtain them from [`GovernanceRegistry.getPoolId()`](/docs/technical-reference/contract-functions/governanceregistry#getpoolid).

Voting, resetting and claiming require the NFT owner or an address approved by the vote-escrow contract. Manage NFT approvals on the vote-escrow contract. `poke` is permissionless.

## Voter Methods [#voter-methods]

### vote [#vote]

Allocate the NFT's voting power proportionally across the supplied pool weights.

```solidity
function vote(
    address _ve,
    uint256 _tokenId,
    uint160[] calldata _poolVote,
    uint256[] calldata _weights
) external
```

| Input Parameter | Type       | Description                                             |
| --------------- | ---------- | ------------------------------------------------------- |
| `_ve`           | address    | The registered vote-escrow contract containing the NFT. |
| `_tokenId`      | uint256    | The NFT to vote with.                                   |
| `_poolVote`     | uint160\[] | The pool identifiers to vote for.                       |
| `_weights`      | uint256\[] | Relative weights, in the same order as `_poolVote`.     |

The arrays must have equal lengths and contain no more than `maxVotingNum()` pools. Each selected pool must have voting rewards deployed and voting authorized. Duplicate pools and allocations that round down to zero revert.

An NFT can vote or deposit into a managed NFT once per epoch. Voting is unavailable during the epoch's initial distribution window. During the final voting window, only whitelisted NFTs can vote. Deactivated managed NFTs cannot vote.

### poke [#poke]

Recalculate an NFT's existing pool allocations using its current weighted voting power. This updates the balances recorded in the associated fee and bribe reward contracts without selecting new pools.

```solidity
function poke(address _ve, uint256 _tokenId) external
```

Anyone can call this method. It is unavailable during the epoch's initial distribution window and requires existing allocations to remain valid.

### reset [#reset]

Remove the NFT's pool allocations and the corresponding balances in fee and bribe reward contracts.

```solidity
function reset(address _ve, uint256 _tokenId) external
```

The caller must own or be approved for the NFT. Resetting is unavailable in the epoch in which the NFT last voted or deposited into a managed NFT, and during the initial distribution window. After a successful reset, the NFT can vote again in the current epoch.

### depositManaged [#depositmanaged]

Deposit an NFT into a managed NFT in the same vote-escrow contract, then update the managed NFT's pool voting balances.

```solidity
function depositManaged(
    address _ve,
    uint256 _tokenId,
    uint256 _mTokenId
) external
```

| Input Parameter | Type    | Description                            |
| --------------- | ------- | -------------------------------------- |
| `_ve`           | address | The registered vote-escrow contract.   |
| `_tokenId`      | uint256 | The NFT to deposit.                    |
| `_mTokenId`     | uint256 | The managed NFT receiving the deposit. |

The caller must own or be approved for `_tokenId`. The managed NFT must be active. The once-per-epoch restriction and initial distribution window apply; deposits are also unavailable during the final voting window. An NFT withdrawn from a managed NFT is locked again for the maximum lock duration.

### withdrawManaged [#withdrawmanaged]

Withdraw an NFT from its managed NFT and update the managed NFT's pool voting balances.

```solidity
function withdrawManaged(address _ve, uint256 _tokenId) external
```

The caller must own or be approved for the NFT. Withdrawal is unavailable in the same epoch as its deposit and during the initial distribution window. The withdrawn NFT is locked again for the maximum lock duration.

### claimBribes [#claimbribes]

Claim voting incentives from multiple bribe reward contracts for one NFT. Rewards are transferred to the NFT's current owner.

```solidity
function claimBribes(
    address[] memory _bribes,
    address[][] memory _tokens,
    address _ve,
    uint256 _tokenId
) external
```

| Input Parameter | Type          | Description                                                  |
| --------------- | ------------- | ------------------------------------------------------------ |
| `_bribes`       | address\[]    | The `BribeVotingReward` contracts to claim from.             |
| `_tokens`       | address\[]\[] | Reward token addresses for each contract, in matching order. |
| `_ve`           | address       | The vote-escrow contract containing the NFT.                 |
| `_tokenId`      | uint256       | The NFT whose recorded rewards are claimed.                  |

The caller must own or be approved for the NFT. Supply one token list for each reward contract.

### claimFees [#claimfees]

Claim pool fee rewards from multiple fee reward contracts for one NFT. Rewards are transferred to the NFT's current owner.

```solidity
function claimFees(
    address[] memory _fees,
    address[][] memory _tokens,
    address _ve,
    uint256 _tokenId
) external
```

| Input Parameter | Type          | Description                                                  |
| --------------- | ------------- | ------------------------------------------------------------ |
| `_fees`         | address\[]    | The `FeesVotingReward` contracts to claim from.              |
| `_tokens`       | address\[]\[] | Reward token addresses for each contract, in matching order. |
| `_ve`           | address       | The vote-escrow contract containing the NFT.                 |
| `_tokenId`      | uint256       | The NFT whose recorded rewards are claimed.                  |

The caller must own or be approved for the NFT. Supply one token list for each reward contract. These methods claim pool voting rewards; rebases use the separate [RewardsDistributor](/docs/technical-reference/contract-functions/rewardsdistributor).

### createVotingRewards [#createvotingrewards]

Create the fee and bribe reward contracts for a registered pool. Anyone can call this method, and only one pair can be created per pool. Creation also authorizes voting for the pool.

```solidity
function createVotingRewards(uint160 _poolId)
    external
    returns (address fees, address bribe)
```

| Parameter | Type    | Description                               |
| --------- | ------- | ----------------------------------------- |
| `_poolId` | uint160 | The registered pool identifier.           |
| `fees`    | address | The created `FeesVotingReward` contract.  |
| `bribe`   | address | The created `BribeVotingReward` contract. |

## Administration Methods [#administration-methods]

These methods are restricted by the contract's [AccessManager](/docs/technical-reference/contract-functions/access-manager) authority.

```solidity
function forceReset(address _ve, uint256 _tokenId) external
function setMaxVotingNum(uint256 _maxVotingNum) external
function whitelistNFT(address _ve, uint256 _tokenId, bool _bool) external
function whitelistToken(address _token, bool _bool) external
function banVote(uint160 _poolId) external
function reauthorizeVote(uint160 _poolId) external
function setGovernanceRegistry(address _governanceRegistry) external
```

`forceReset` removes an NFT's allocations under the same epoch and distribution-window restrictions as `reset`. `setMaxVotingNum` changes the maximum pool count and requires a value of at least 10. `whitelistNFT` controls access to the final voting window; `whitelistToken` controls whether a new token can be added as a bribe reward. `banVote` and `reauthorizeVote` change whether a pool with deployed voting rewards accepts votes.

## View Methods [#view-methods]

### governanceRegistry [#governanceregistry]

Return the governance registry address.

```solidity
function governanceRegistry() external view returns (address)
```

### totalWeight [#totalweight]

Return the total weight currently allocated across pools.

```solidity
function totalWeight() external view returns (uint256)
```

### maxVotingNum [#maxvotingnum]

Return the maximum number of pools an NFT can vote for in one call.

```solidity
function maxVotingNum() external view returns (uint256)
```

### poolIds [#poolids]

Return the pool identifier at an index in the list of pools with voting rewards.

```solidity
function poolIds(uint256 _index) external view returns (uint160)
```

### length [#length]

Return the number of pools with voting rewards. Enumerate them with `poolIds(index)`.

```solidity
function length() external view returns (uint256)
```

### hasVotingRewards [#hasvotingrewards]

Return whether fee and bribe reward contracts have been created for a pool.

```solidity
function hasVotingRewards(uint160 _poolId) external view returns (bool)
```

### poolToFees [#pooltofees]

Return the fee reward contract associated with a pool.

```solidity
function poolToFees(uint160 _poolId) external view returns (address)
```

### poolToBribe [#pooltobribe]

Return the bribe reward contract associated with a pool.

```solidity
function poolToBribe(uint160 _poolId) external view returns (address)
```

### weights [#weights]

Return the total weight currently allocated to a pool.

```solidity
function weights(uint160 _poolId) external view returns (uint256)
```

### votes [#votes]

Return the weight allocated by an NFT to a pool.

```solidity
function votes(address _ve, uint256 tokenId, uint160 poolId)
    external view returns (uint256)
```

### poolVote [#poolvote]

Return the pool identifier at an index in an NFT's current pool allocations.

```solidity
function poolVote(address _ve, uint256 tokenId, uint256 index)
    external view returns (uint160)
```

### usedWeights [#usedweights]

Return the total weight currently allocated by an NFT.

```solidity
function usedWeights(address _ve, uint256 tokenId) external view returns (uint256)
```

### lastVoted [#lastvoted]

Return the timestamp when an NFT last voted or deposited into a managed NFT.

```solidity
function lastVoted(address _ve, uint256 tokenId) external view returns (uint256)
```

### isWhitelistedToken [#iswhitelistedtoken]

Return whether a token is whitelisted for addition as a new bribe reward token.

```solidity
function isWhitelistedToken(address token) external view returns (bool)
```

### isWhitelistedNFT [#iswhitelistednft]

Return whether an NFT can vote during the final voting window.

```solidity
function isWhitelistedNFT(address _ve, uint256 tokenId) external view returns (bool)
```

### isVoteAuthorized [#isvoteauthorized]

Return whether voting is authorized for a pool.

```solidity
function isVoteAuthorized(uint160 _poolId) external view returns (bool)
```
