# RewardsDistributor



## Overview [#overview]

`RewardsDistributor` records weekly SPECTRA rebases for [VotingEscrow](/docs/technical-reference/contract-functions/votingescrow) NFTs. Each claim identifies a lock by its `uint256` token ID. Pool voting fees and bribes use the [Voter](/docs/technical-reference/contract-functions/voter) and [VotingReward](/docs/technical-reference/contract-functions/votingreward) interfaces instead.

<Callout type="info">
  Weekly emissions and the rebase are zero under [SGP-20](https://paragraph.com/@spectra/sgp-20-is-now-in-effect-spectra-emissions-reduced-to-zero). The pool swap-fee share previously allocated to veSPECTRA voters is routed to the DAO treasury under [SGP-19](https://snapshot.box/#/s:spectradao.eth/proposal/0xd1a081c2783ba428627fbafa2a65d9d26571eae45647917d45bd7571d18a493b). These methods operate on recorded distributions; the existence of a claim method does not imply a new reward allocation.
</Callout>

## Read claimable rebases [#read-claimable-rebases]

```solidity
function claimable(uint256 _tokenId) external view returns (uint256 claimable_)
```

Returns the SPECTRA amount claimable for a lock NFT, in the token's smallest units. The calculation uses the NFT's voting power and the total voting power at the end of each completed, checkpointed week. Each calculation processes at most 50 weeks starting at the NFT's claim cursor.

## Claim rebases [#claim-rebases]

```solidity
function claim(uint256 _tokenId) external returns (uint256)
function claimMany(uint256[] calldata _tokenIds) external returns (bool)
```

Anyone can trigger a claim. The caller cannot choose the recipient:

* For an unexpired or permanent lock, the distributor adds the claimed SPECTRA to that NFT's locked balance through `depositFor`.
* For an expired, nonpermanent lock, the distributor transfers the claimed SPECTRA to the NFT owner.
* An NFT deposited into a managed lock cannot claim directly through these methods.

`claim` returns the amount claimed. `claimMany` applies the same behavior to each token ID and returns `true` on success; a zero token ID ends processing of the array. A reverting claim reverts the batch.

Each claim processes at most 50 weeks and updates `timeCursorOf(_tokenId)`. Call again if additional completed weeks remain before the week containing `lastTokenTime()`. Claim recorded rewards before withdrawing, merging, or splitting a lock, because these operations burn NFT IDs.

## Record a distribution [#record-a-distribution]

```solidity
function checkpointToken() external
```

Records newly received SPECTRA and allocates it across weekly distribution buckets. This method is restricted by the contract's AccessManager authority. It does not mint SPECTRA or start new emissions.

## Distribution state [#distribution-state]

```solidity
function ve() external view returns (IVotingEscrow)
function token() external view returns (address)
function governanceRegistry() external view returns (address)
function startTime() external view returns (uint256)
function lastTokenTime() external view returns (uint256)
function timeCursorOf(uint256 tokenId) external view returns (uint256)
function tokensPerWeek(uint256 week) external view returns (uint256)
```

`ve` identifies the escrow whose NFT IDs this distributor accepts. `token` identifies the distributed ERC-20 token. `timeCursorOf` is the next week to process for an NFT; an unclaimed NFT initially has a zero cursor. Query `tokensPerWeek` using the Unix timestamp of a week boundary, rounded down to a multiple of 604800 seconds.
