# VotingReward



## Overview [#overview]

`VotingReward` is the shared implementation used by [FeesVotingReward](/docs/technical-reference/contract-functions/votingreward/feesvotingreward) and [BribeVotingReward](/docs/technical-reference/contract-functions/votingreward/bribevotingreward) to distribute rewards to pool voters. Each voting position is identified by its vote-escrow contract address (`ve`) and NFT identifier (`tokenId`).

<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, and [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. These methods describe the reward contract's API. For protocol decisions, see the [governance guide](/docs/guides/voting-and-earning-rewards).
</Callout>

Balances in this contract represent the voting weights recorded by `Voter` for pool allocations. Balances and total supply are tracked separately for each vote-escrow contract. Reward funding is assigned to the current weekly epoch. When several voting escrows are registered, funding is split between them according to their weighted voting power at the epoch's start, as reported by the governance registry's aggregator.

Rewards become claimable after the epoch ends. For each completed epoch, `earned` uses the NFT's last balance checkpoint and its escrow's last supply checkpoint in that epoch to calculate its share. Rebases are handled separately by [RewardsDistributor](/docs/technical-reference/contract-functions/rewardsdistributor).

## VotingReward Methods [#votingreward-methods]

### getReward [#getreward]

Claim the selected reward tokens for an NFT. The caller must own or be approved for the NFT, or be the `Voter` contract. Tokens are transferred to the NFT's current owner, including when an approved operator calls.

```solidity
function getReward(address ve, uint256 tokenId, address[] memory tokens) public
```

| Input Parameter | Type       | Description                                  |
| --------------- | ---------- | -------------------------------------------- |
| `ve`            | address    | The vote-escrow contract containing the NFT. |
| `tokenId`       | uint256    | The NFT whose recorded rewards are claimed.  |
| `tokens`        | address\[] | The reward token addresses to claim.         |

The claim updates `lastEarn` for each selected reward token. It excludes rewards assigned to the current, incomplete epoch.

### \_deposit [#_deposit]

Increase an NFT's recorded voting balance and its escrow's total supply, then write balance and supply checkpoints. This method updates voting-weight accounting.

```solidity
function _deposit(address ve, uint256 amount, uint256 tokenId) public
```

| Input Parameter | Type    | Description                                  |
| --------------- | ------- | -------------------------------------------- |
| `ve`            | address | The vote-escrow contract containing the NFT. |
| `amount`        | uint256 | The voting weight to add.                    |
| `tokenId`       | uint256 | The NFT whose voting balance is updated.     |

This public method is used when `Voter` records pool allocations. Access is restricted by the contract's [AccessManager](/docs/technical-reference/contract-functions/access-manager) authority.

### \_withdraw [#_withdraw]

Decrease an NFT's recorded voting balance and its escrow's total supply, then write balance and supply checkpoints.

```solidity
function _withdraw(address ve, uint256 amount, uint256 tokenId) public
```

| Input Parameter | Type    | Description                                  |
| --------------- | ------- | -------------------------------------------- |
| `ve`            | address | The vote-escrow contract containing the NFT. |
| `amount`        | uint256 | The voting weight to remove.                 |
| `tokenId`       | uint256 | The NFT whose voting balance is updated.     |

This is a restricted method used when `Voter` removes or updates pool allocations.

### notifyRewardAmount [#notifyrewardamount]

Fund rewards for the current epoch with an ERC-20 token. Funding permissions differ between [FeesVotingReward](/docs/technical-reference/contract-functions/votingreward/feesvotingreward#notifyrewardamount) and [BribeVotingReward](/docs/technical-reference/contract-functions/votingreward/bribevotingreward#notifyrewardamount).

```solidity
function notifyRewardAmount(address token, uint256 amount) external
```

### setGovernanceRegistry [#setgovernanceregistry]

Change the governance registry address. This method is restricted by the contract's AccessManager authority.

```solidity
function setGovernanceRegistry(address _governanceRegistry) external
```

## View Methods [#view-methods]

### DURATION [#duration]

Return the epoch duration constant, 7 days in seconds.

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

### voter [#voter]

Return the `Voter` address configured in the governance registry.

```solidity
function voter() public view returns (address)
```

### governanceRegistry [#governanceregistry]

Return the governance registry address.

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

### totalSupply [#totalsupply]

Return the total voting weight currently recorded for an escrow in this reward contract.

```solidity
function totalSupply(address ve) external view returns (uint256)
```

### balanceOf [#balanceof]

Return the voting weight currently recorded for an NFT in this reward contract.

```solidity
function balanceOf(address ve, uint256 tokenId) external view returns (uint256)
```

### tokenRewardsPerEpoch [#tokenrewardsperepoch]

Return the amount of a reward token assigned to an escrow for a given epoch.

```solidity
function tokenRewardsPerEpoch(address ve, address token, uint256 epochStart)
    external view returns (uint256)
```

`epochStart` is the epoch's Unix start timestamp, rounded down to a multiple of `DURATION()`.

### lastEarn [#lastearn]

Return the most recent claim timestamp for an NFT and reward token.

```solidity
function lastEarn(address ve, address token, uint256 tokenId)
    external view returns (uint256)
```

### rewards [#rewards]

Return the reward token address at an index in the contract's reward token list.

```solidity
function rewards(uint256 index) external view returns (address)
```

### rewardsListLength [#rewardslistlength]

Return the number of reward tokens. Enumerate them with `rewards(index)`.

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

### isReward [#isreward]

Return whether a token has been added to this reward contract's token list.

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

### numCheckpoints [#numcheckpoints]

Return the number of balance checkpoints for an NFT.

```solidity
function numCheckpoints(address ve, uint256 tokenId)
    external view returns (uint256)
```

### supplyNumCheckpoints [#supplynumcheckpoints]

Return the number of supply checkpoints for an escrow.

```solidity
function supplyNumCheckpoints(address ve) external view returns (uint256)
```

### checkpoints [#checkpoints]

Return a balance checkpoint's timestamp and voting weight. Multiple changes in one epoch update the same checkpoint.

```solidity
function checkpoints(address ve, uint256 tokenId, uint256 index)
    external view returns (uint256 timestamp, uint256 balanceOf)
```

### supplyCheckpoints [#supplycheckpoints]

Return a supply checkpoint's timestamp and total voting weight. Multiple changes in one epoch update the same checkpoint.

```solidity
function supplyCheckpoints(address ve, uint256 index)
    external view returns (uint256 timestamp, uint256 supply)
```

### getPriorBalanceIndex [#getpriorbalanceindex]

Return the index of the latest balance checkpoint at or before a Unix timestamp.

```solidity
function getPriorBalanceIndex(address ve, uint256 tokenId, uint256 timestamp)
    public view returns (uint256)
```

Use the returned index with `checkpoints(ve, tokenId, index)` to read its timestamp and balance. The method returns zero when no checkpoint exists or the timestamp precedes the first checkpoint; check `numCheckpoints` and the returned checkpoint's timestamp before interpreting that result. A timestamp after the latest checkpoint returns the latest index.

### getPriorSupplyIndex [#getpriorsupplyindex]

Return the index of the latest supply checkpoint at or before a Unix timestamp.

```solidity
function getPriorSupplyIndex(address ve, uint256 timestamp)
    public view returns (uint256)
```

The method returns zero when no checkpoint exists or the timestamp precedes the first checkpoint; check `supplyNumCheckpoints` and the returned checkpoint's timestamp. A timestamp after the latest checkpoint returns the latest index.

### earned [#earned]

Return the unclaimed reward amount for an NFT and reward token across completed epochs.

```solidity
function earned(address ve, address token, uint256 tokenId)
    public view returns (uint256)
```

| Input Parameter | Type    | Description                                  |
| --------------- | ------- | -------------------------------------------- |
| `ve`            | address | The vote-escrow contract containing the NFT. |
| `token`         | address | The reward token to query.                   |
| `tokenId`       | uint256 | The NFT whose rewards are queried.           |

This view does not claim rewards or update `lastEarn`. It returns zero if the NFT has no recorded balance checkpoints.
