Voter

Git Source

Inherits: IVoter, InfraredUpgradeable, ReentrancyGuardUpgradeable

Author: Modified from Velodrome (https://github.com/velodrome-finance/contracts/blob/main/contracts/Voter.sol)

Ensure new epoch before voting and manage staking tokens and bribe vaults.

This contract manages votes for POL CuttingBoard allocation and respective bribeVault creation. It also provides support for depositing and withdrawing from managed veNFTs. Inspired by Velodrome V2 Voter.

State Variables

ve

Returns the VotingEscrow contract address

address public ve;

totalWeight

Returns total voting weight across all votes

uint256 public totalWeight;

maxVotingNum

Returns maximum number of staking tokens one voter can vote for

uint256 public maxVotingNum;

MIN_MAXVOTINGNUM

Minimum allowed value for maximum voting number

Used as validation threshold in setMaxVotingNum

uint256 internal constant MIN_MAXVOTINGNUM = 1;

feeVault

Returns global fee distribution vault address

address public feeVault;

stakingTokens

Internal array of all staking tokens with active bribe vaults Used for token enumeration and state tracking

address[] public stakingTokens;

bribeVaults

Returns bribe vault address for a given staking token

mapping(address => address) public bribeVaults;

weights

Returns total weight allocated to a staking token

mapping(address => uint256) public weights;

votes

Returns vote weight allocated by token ID for specific staking token

mapping(uint256 => mapping(address => uint256)) public votes;

stakingTokenVote

NFT => List of stakingTokens voted for by NFT

mapping(uint256 => address[]) public stakingTokenVote;

usedWeights

Returns total vote weight used by specific token ID

mapping(uint256 => uint256) public usedWeights;

lastVoted

Returns timestamp of last vote for a token ID

mapping(uint256 => uint256) public lastVoted;

isWhitelistedNFT

Checks if NFT is whitelisted for special voting

mapping(uint256 => bool) public isWhitelistedNFT;

isAlive

Checks if bribe vault is active

mapping(address => bool) public isAlive;

Functions

onlyNewEpoch

Ensures operations only occur in new epochs and outside distribution window

Validates both epoch transition and proper timing within epoch

modifier onlyNewEpoch(uint256 _tokenId);

Parameters

NameTypeDescription
_tokenIduint256The token ID to check last vote timestamp for

epochStart

Calculates start of epoch containing timestamp

function epochStart(uint256 _timestamp) external pure returns (uint256);

Parameters

NameTypeDescription
_timestampuint256Input timestamp

Returns

NameTypeDescription
<none>uint256Start of epoch time

epochNext

Calculates start of next epoch after timestamp

function epochNext(uint256 _timestamp) external pure returns (uint256);

Parameters

NameTypeDescription
_timestampuint256Input timestamp

Returns

NameTypeDescription
<none>uint256Start of next epoch time

epochVoteStart

Calculates start of voting window for epoch containing timestamp

function epochVoteStart(uint256 _timestamp) external pure returns (uint256);

Parameters

NameTypeDescription
_timestampuint256Input timestamp

Returns

NameTypeDescription
<none>uint256Vote window start time

epochVoteEnd

Calculates end of voting window for epoch containing timestamp

function epochVoteEnd(uint256 _timestamp) external pure returns (uint256);

Parameters

NameTypeDescription
_timestampuint256Input timestamp

Returns

NameTypeDescription
<none>uint256Vote window end time

constructor

Constructor for Voter contract

Reverts if infrared address is zero

constructor(address _infrared) InfraredUpgradeable(_infrared);

Parameters

NameTypeDescription
_infraredaddressAddress of the Infrared contract

initialize

Initializes the Voter contract with the voting escrow and fee vault

Sets up initial state including fee vault with configured reward tokens

function initialize(address _ve, address _gov, address _keeper)
    external
    initializer;

Parameters

NameTypeDescription
_veaddressAddress of the voting escrow contract
_govaddressAddress of the governance multisig
_keeperaddressAddress of the keeper

setMaxVotingNum

Updates maximum allowed votes per voter

function setMaxVotingNum(uint256 _maxVotingNum) external onlyGovernor;

Parameters

NameTypeDescription
_maxVotingNumuint256New maximum number of allowed votes

reset

Resets voting state for a token ID

Required before making changes to veNFT state

function reset(uint256 _tokenId) external onlyNewEpoch(_tokenId) nonReentrant;

Parameters

NameTypeDescription
_tokenIduint256veNFT token ID to reset

_reset

Resets vote state for a token ID

Cleans up all vote accounting and emits appropriate events

function _reset(uint256 _tokenId) internal;

Parameters

NameTypeDescription
_tokenIduint256Token ID to reset voting state for

poke

Updates voting balances in rewards contracts for a token ID

Should be called after any action that affects vote weight

function poke(uint256 _tokenId) external nonReentrant;

Parameters

NameTypeDescription
_tokenIduint256veNFT token ID to update

_poke

Updates voting power for a token ID

Recalculates and updates all vote weightings

function _poke(uint256 _tokenId, uint256 _weight) internal;

Parameters

NameTypeDescription
_tokenIduint256Token ID to update voting power for
_weightuint256New voting power weight to apply

_vote

Core voting logic to allocate weights to staking tokens

Handles vote accounting, reward deposits and event emissions

*Implementation sequence:

  1. Reset all existing votes and accounting via _reset
  2. Calculate total vote weight for normalizing allocations
  3. For each staking token:
  • Validate bribe vault exists and is active
  • Calculate and apply normalized vote weight
  • Update token-specific accounting
  • Deposit into bribe vault
  1. Update global vote accounting if votes were cast
  2. If _isPoke is true, skip processing for tokens with killed bribe vaults*
function _vote(
    uint256 _tokenId,
    uint256 _weight,
    address[] memory _stakingTokenVote,
    uint256[] memory _weights,
    bool _isPoke
) internal;

Parameters

NameTypeDescription
_tokenIduint256Token ID that is voting
_weightuint256Total voting power weight available
_stakingTokenVoteaddress[]Array of staking tokens to vote for
_weightsuint256[]Array of weights to allocate to each token
_isPokeboolif fees should be deposited in addition to marking tokenId as voted

vote

Distributes voting weight to multiple staking tokens

Weight is allocated proportionally based on provided weights

function vote(
    uint256 _tokenId,
    address[] calldata _stakingTokenVote,
    uint256[] calldata _weights
) external onlyNewEpoch(_tokenId) nonReentrant;

Parameters

NameTypeDescription
_tokenIduint256veNFT token ID voting with
_stakingTokenVoteaddress[]Array of staking token addresses receiving votes
_weightsuint256[]Array of weights to allocate to each token

depositManaged

Deposits veNFT into a managed NFT

NFT will be re-locked to max time on withdrawal

function depositManaged(uint256 _tokenId, uint256 _mTokenId)
    external
    nonReentrant
    onlyNewEpoch(_tokenId);

Parameters

NameTypeDescription
_tokenIduint256veNFT token ID to deposit
_mTokenIduint256Managed NFT token ID to deposit into

withdrawManaged

Withdraws veNFT from a managed NFT

Withdrawing locks NFT to max lock time

function withdrawManaged(uint256 _tokenId)
    external
    nonReentrant
    onlyNewEpoch(_tokenId);

Parameters

NameTypeDescription
_tokenIduint256veNFT token ID to withdraw

isWhitelistedToken

Checks if a token is whitelisted for rewards

function isWhitelistedToken(address _token) external view returns (bool);

Parameters

NameTypeDescription
_tokenaddress

Returns

NameTypeDescription
<none>boolTrue if token is whitelisted

whitelistNFT

Updates whitelist status for veNFT for privileged voting

function whitelistNFT(uint256 _tokenId, bool _bool) external onlyGovernor;

Parameters

NameTypeDescription
_tokenIduint256veNFT token ID to update
_boolboolNew whitelist status

createBribeVault

Creates new bribe vault for staking token

function createBribeVault(address _stakingToken, address[] calldata _rewards)
    external
    onlyKeeper
    nonReentrant
    whenInitialized
    returns (address);

Parameters

NameTypeDescription
_stakingTokenaddressAddress of staking token
_rewardsaddress[]

Returns

NameTypeDescription
<none>addressAddress of created bribe vault

killBribeVault

Disables a bribe vault

function killBribeVault(address _stakingToken) external onlyGovernor;

Parameters

NameTypeDescription
_stakingTokenaddressAddress of staking token for vault to disable

reviveBribeVault

Re-enables a disabled bribe vault

function reviveBribeVault(address _stakingToken) external onlyGovernor;

Parameters

NameTypeDescription
_stakingTokenaddressAddress of staking token for vault to re-enable

length

Returns number of staking tokens with active bribe vaults

function length() external view returns (uint256);

Returns

NameTypeDescription
<none>uint256Count of staking tokens with bribe vaults

claimBribes

Claims bribes from multiple sources for a veNFT

function claimBribes(
    address[] memory _bribes,
    address[][] memory _tokens,
    uint256 _tokenId
) external;

Parameters

NameTypeDescription
_bribesaddress[]Array of bribe vault addresses to claim from
_tokensaddress[][]Array of reward tokens to claim for each vault
_tokenIduint256veNFT token ID to claim for

claimFees

Claims fee rewards for a veNFT

function claimFees(address[] memory _tokens, uint256 _tokenId) external;

Parameters

NameTypeDescription
_tokensaddress[]Array of fee tokens to claim
_tokenIduint256veNFT token ID to claim for

getStakingTokenWeights

Returns all staking tokens and their current voting weights

Helper function that aggregates staking token data

function getStakingTokenWeights()
    public
    view
    returns (
        address[] memory _stakingTokens,
        uint256[] memory _weights,
        uint256 _totalWeight
    );

Returns

NameTypeDescription
_stakingTokensaddress[]Array of staking token addresses
_weightsuint256[]Array of voting weights corresponding to each token
_totalWeightuint256Sum of all voting weights