EscrowVoteManagerV1
Overview
EscrowVoteManagerV1 is a smart contract that manages voting power distribution and reward allocation for gauge contracts associated with various pools in the EYWA ecosystem. It integrates with the escrow manager, gauge and rewards distributor factories, and the emission manager to facilitate:
Voting with Locked Tokens: Users holding escrowed (locked) EYWA tokens can vote on pools to direct emissions (rewards) toward specific gauges.
Gauge Creation and Management: Authorized entities (e.g., owner/DAO) can create, kill, and revive gauges for different pools, enabling dynamic reward allocation.
Rewards Distribution: The contract accumulates reward amounts from the emission manager and distributes them proportionally to gauges based on the votes cast in previous epochs.
Token Whitelisting: Maintains a whitelist of tokens eligible for reward distributions.
By leveraging epoch-based logic and integrating closely with the emission manager and escrow manager, EscrowVoteManagerV1 ensures a fair and flexible governance mechanism that aligns incentives between token holders and liquidity pools.
Inherited Contracts and Interfaces
UUPSUpgradeable: Manages upgrade logic for UUPS (Universal Upgradeable Proxy Standard) deployments.
OwnableUpgradeable: Provides ownership access control, allowing only the contract owner to perform certain critical operations.
IEscrowVoteManagerV1: Defines the interface for managing gauge votes, reward notifications, and incentive claims.
Additional External References:
SafeERC20, IERC20: Used for safe interactions with ERC20 tokens.
Math: Utility library for math operations.
IEscrowManager: Provides access to escrowed token balances, voting checks, and owner references.
IRewardsDistributorFactoryV1: Factory contract for creating rewards distributors associated with gauges.
IGaugeFactoryV1: Factory contract for creating gauge contracts for pools.
IGaugeV1: Interface for gauge contracts that handle reward distribution to liquidity providers.
IEmissionManagerV1: Manages weekly emissions and provides current epoch information.
IRewardsDistributor: Distributes incentives and handles depositing/withdrawing user votes.
IDistributionCreator: Provides campaign parameters for gauge creation and reward distribution campaigns.
Constants
EPOCH_DURATION
EPOCH_DURATION
Type:
uint256
Value:
1 weeks
Description: Duration of each epoch in seconds. Aligns voting and reward distribution schedules.
PRECISION
PRECISION
Type:
uint256
Value:
1e18
Description: Precision factor used for calculations to maintain integer arithmetic accuracy.
State Variables
Core Addresses and Interfaces
s_emissionManager
Type:
address
Description: Address of the emission manager contract that controls weekly EYWA emissions.
s_eywa
Type:
address
Description: The address of the EYWA token contract.
s_escrowManager
Type:
IEscrowManager
Description: Interface to the escrow manager contract, which handles locked tokens and provides voting power data.
s_rewardsDistributorFactory
Type:
IRewardsDistributorFactoryV1
Description: Factory for creating incentive rewards distributors for new gauges.
s_gaugeFactory
Type:
IGaugeFactoryV1
Description: Factory for creating new gauge contracts associated with pools.
Voting and Distribution
_s_distributionIndex
Type:
uint256
Description: Global distribution index used to calculate claimable rewards for each gauge, updated when new rewards are notified.
s_pools
Type:
address[]
Description: Array of registered pool addresses. Each pool can have an associated gauge.
s_gaugeByPool
Type:
mapping (address => address)
Description: Maps a pool address to its corresponding gauge address.
s_poolByGauge
Type:
mapping (address => address)
Description: Reverse mapping from a gauge address to its associated pool.
s_incentiveRewardsDistributorByGauge
Type:
mapping (address => address)
Description: Maps a gauge to its incentive rewards distributor address, where votes are deposited and rewards claimed.
s_votesByEpochAndPool
Type:
mapping (uint256 => mapping (address => uint256))
Description: Tracks total votes allocated to each pool per epoch start timestamp.
s_claimableRewardsByGauge
Type:
mapping (address => uint256)
Description: Accumulated claimable EYWA rewards for each gauge. Distributed when
_distributeRewards
is called.
s_lastDistributionTimestampByGauge
Type:
mapping (address => uint256)
Description: Tracks the last distribution timestamp for each gauge to ensure rewards are distributed after an epoch update.
s_isGauge
Type:
mapping (address => bool)
Description: Indicates if a given address is recognized as a gauge.
s_isWhitelistedToken
Type:
mapping (address => bool)
Description: Indicates if a token is whitelisted for incentive distribution.
s_isActiveGauge
Type:
mapping (address => bool)
Description: Indicates if a gauge is currently active and eligible for rewards.
Token Voting
s_usedVotesByTokenId
Type:
mapping (uint256 => uint256)
Description: The number of votes currently used (allocated) by a particular escrowed token ID.
s_lastVotedTimestampByTokenId
Type:
mapping (uint256 => uint256)
Description: Timestamp of the last vote cast by each token ID, used to determine if votes can be reset or updated.
s_votedPoolsByTokenId
Type:
mapping (uint256 => address[])
Description: The list of pools a given token ID has voted for in the current epoch.
s_totalVotesByEpoch
Type:
mapping (uint256 => uint256)
Description: Total votes cast across all pools in a given epoch.
s_votesByTokenIdAndPool
Type:
mapping (uint256 => mapping (address => uint256))
Description: Number of votes allocated by a specific token ID to a particular pool.
Distribution Indexing
_s_supplyDistributionIndex
Type:
mapping (address => uint256)
Description: The distribution index per gauge. Used in reward calculation to determine how much of the globally notified rewards a gauge can claim.
Constructor
constructor()
Description: Disables initializers to prevent re-initialization of upgradeable contracts.
External Functions
initialize(...)
initialize(...)
Signature:
Description: Initializes the contract state, sets the owner, references to external contracts, and whitelists initial tokens.
Parameters:
owner_
: Address of the contract owner.emissionManager_
: Address of the emission manager contract.eywa_
: Address of the EYWA token contract.escrowManager_
: Reference to the escrow manager contract.rewardsDistributorFactory_
: Reference to the rewards distributor factory.gaugeFactory_
: Reference to the gauge factory.whitelistedTokens_
: Array of token addresses to whitelist initially.
Effects:
Sets core addresses and interfaces.
Marks given tokens as whitelisted.
Transfers contract ownership to
owner_
.
createGauge(...)
createGauge(...)
Signature:
Description: Creates a new gauge for a specified pool. Also creates an associated incentive rewards distributor. Only callable by the owner.
Parameters:
pool_
: Address of the pool for which the gauge is created.campaignParameters_
: Parameters defining the reward distribution campaign.
Constraints & Checks:
The gauge must not already exist for the given pool.
Effects:
Deploys a new gauge via the gauge factory.
Deploys a new incentive rewards distributor.
Maps the new gauge and distributor to the pool.
Marks the gauge as active and emits
GaugeCreated
.
killGauge(...)
killGauge(...)
Signature:
Description: Deactivates a gauge, preventing it from receiving future rewards. Unclaimed rewards are returned to the emission managerβs treasury.
Parameters:
gauge_
: Address of the gauge to deactivate.
Constraints & Checks:
The gauge must be active.
Effects:
Transfers any claimable rewards back to the emission managerβs treasury.
Marks the gauge as inactive.
Emits
GaugeKilled
.
reviveGauge(...)
reviveGauge(...)
Signature:
Description: Reactivates a previously killed gauge, allowing it to receive rewards again.
Parameters:
gauge_
: Address of the gauge to reactivate.
Constraints & Checks:
The gauge must not already be active.
Effects:
Marks the gauge as active.
Emits
GaugeRevived
.
setWhitelistStatusForTokens(...)
setWhitelistStatusForTokens(...)
Signature:
Description: Updates the whitelist status for a batch of tokens. Only callable by the owner.
Parameters:
tokens_
: Array of token addresses to update.statuses_
: Matching array of boolean values, true to whitelist, false to remove.
Constraints & Checks:
Length of
tokens_
must matchstatuses_
.
Effects:
Updates the whitelist status of each token.
Emits
WhitelistStatusUpdatedForTokens
.
vote(...)
vote(...)
Signature:
Description:
Casts votes for specified pools using the given escrowed token IDβs voting power. The voting power is sourced from IEscrowManager
. The caller must be authorized to operate tokenId_
.
Parameters:
tokenId_
: ID of the escrowed token used to vote.pools_
: Array of pool addresses to vote for.weights_
: Relative weights allocated to each pool.
Checks:
Arrays
pools_
andweights_
must be non-empty and of equal length.Caller must be authorized for
tokenId_
.
Effects:
Calls
_vote
internally to allocate votes.Updates the last voted timestamp for
tokenId_
.
reset(...)
reset(...)
Signature:
Description:
Resets votes for a given token ID, withdrawing allocated votes from all pools. The caller must be authorized for tokenId_
.
Parameters:
tokenId_
: ID of the token whose votes are reset.
Effects:
Calls
_reset
internally to remove existing votes.Updates the last voted timestamp for
tokenId_
.
poke(...)
poke(...)
Signature:
Description:
Recalculates and updates votes for the specified token ID based on its current voting power. Useful if the tokenβs voting power changed. The caller must be authorized for tokenId_
.
Parameters:
tokenId_
: ID of the token to recalculate votes for.
Effects:
Retrieves previously voted pools and weights.
Calls
_vote
again to update allocations according to new voting power.Updates the last voted timestamp for
tokenId_
.
claimIncentives(...)
claimIncentives(...)
Signature:
Description: Allows the caller to claim incentive rewards from multiple distributors. Each distributor may offer multiple tokens as rewards.
Parameters:
incentiveRewardsDistributors_
: Array of distributor addresses.rewardTokens_
: Parallel array of reward tokens per distributor.
Effects:
For each distributor, calls
getReward
to transfer earned tokens to the caller.
notifyRewardAmount(...)
notifyRewardAmount(...)
Signature:
Description: Notifies the contract of a new EYWA reward amount to distribute. Only callable by the emission manager.
Parameters:
rewardAmount_
: Amount of EYWA tokens to be distributed as rewards.
Effects:
Calculates the per-vote weight increase (
_s_distributionIndex
update).Emits
RewardNotified
.
distributeRewardsForMultipleGauges(...)
distributeRewardsForMultipleGauges(...)
Signature:
Description: Distributes accumulated rewards to an array of specified gauges. Updates the epoch before distribution.
Parameters:
gauges_
: Array of gauge addresses to distribute rewards to.
Effects:
Calls
_distributeRewards
for each gauge.
distributeRewardsForGaugesInRange(...)
distributeRewardsForGaugesInRange(...)
Signature:
Description:
Distributes accumulated rewards to gauges in a specified range of the s_pools
array. Updates the epoch before distribution.
Parameters:
start_
: Starting index ins_pools
.end_
: Ending index ins_pools
.
Effects:
Iterates over the specified range of pools.
Calls
_distributeRewards
for each gauge.
getPoolsCount()
getPoolsCount()
Signature:
Description: Returns the total number of registered pools.
Return:
uint256
: The number of pools.
nextEpochStart()
nextEpochStart()
Signature:
Description: Returns the timestamp of the next epoch start.
Return:
uint256
: Timestamp for the next epochβs start.
currentEpochStart()
currentEpochStart()
Signature:
Description: Returns the timestamp of the current epoch start.
Return:
uint256
: Timestamp for the current epochβs start.
Internal Functions
_vote(...)
_vote(...)
Signature:
Description: Allocates voting power to specified pools, updating epoch-based vote counts and depositing votes into incentive rewards distributors.
Logic:
_reset(tokenId_)
to remove old votes.Compute total weight sum and allocate votes proportionally to each pool.
Update
s_votesByEpochAndPool
ands_votesByTokenIdAndPool
.Deposit votes into the incentive rewards distributor.
Update
s_totalVotesByEpoch
and sets_usedVotesByTokenId
.
_reset(...)
_reset(...)
Signature:
Description: Removes existing votes for a token ID, withdrawing votes from incentive distributors and updating epoch totals.
Logic:
Retrieve previously voted pools.
For each pool, remove allocated votes from
s_votesByEpochAndPool
ands_votesByTokenIdAndPool
.Withdraw votes from incentive rewards distributors, if applicable.
Update
s_totalVotesByEpoch
ands_usedVotesByTokenId
.
_distributeRewards(...)
_distributeRewards(...)
Signature:
Description: Distributes accumulated claimable rewards to a specific gauge if the current epoch has advanced and the gauge is active.
Logic:
Ensure gauge is active and current epoch is beyond last distribution time.
Update reward indexes with
_updateRewardIndexForGauge
.Transfer claimable rewards to the gauge and call
notifyRewardAmount
on the gauge.Reset
s_claimableRewardsByGauge[gauge_]
and record distribution event.
_updateRewardIndexForGauge(...)
_updateRewardIndexForGauge(...)
Signature:
Description:
Updates the reward index for a gauge based on previous epochβs votes and the global _s_distributionIndex
.
Logic:
Retrieve last epochβs votes for the gaugeβs pool.
Calculate the delta in the global distribution index since last update.
Increase
s_claimableRewardsByGauge[gauge_]
by the proportionate amount.Store the new distribution index state for the gauge.
Events
GaugeCreated
: Emitted when a new gauge is created.GaugeKilled
: Emitted when a gauge is deactivated.GaugeRevived
: Emitted when a gauge is reactivated.WhitelistStatusUpdatedForTokens
: Emitted when token whitelist statuses are updated.RewardNotified
: Emitted when a new reward amount is notified.VoteCast
: Emitted when a token ID casts votes for a pool.VotesAbstained
: Emitted when votes are reset (abstained) for a token ID.RewardsDistributed
: Emitted when rewards are distributed to a gauge.
Errors
GaugeDoesNotExist()
: Thrown if no gauge exists for the provided pool.GaugeAlreadyExists()
: Thrown if trying to create a gauge for a pool that already has one.GaugeNotActive()
: Thrown if attempting to interact with an inactive gauge.GaugeAlreadyActive()
: Thrown if attempting to revive a gauge that is already active.UnauthorizedAccess()
: Thrown if caller is not authorized for the requested action.InvalidArrayLengths()
: Thrown if input arrays differ in length when they should match.ZeroEntry()
: Thrown if a zero allocation occurs where a nonzero value is expected.AlreadyVoted()
: Thrown if a token ID attempts to vote again without resetting.
Summary
EscrowVoteManagerV1 provides a robust and upgradeable system for directing EYWA token emissions to liquidity pools through gauges. By enabling authorized changes to gauges, handling epochs and voting power distributions, and offering flexible reward claims, it aligns user incentives with protocol growth. Its modular integration with escrow managers, gauge factories, and reward distributors ensures a scalable and fair distribution of rewards based on community-driven voting power.
Last updated