IncentiveRewardsDistributor

Overview

IncentiveRewardsDistributor is a reward distribution contract closely integrated with the escrow voting and token locking ecosystem of EYWA. It leverages and extends the core logic from RewardsDistributor, providing:

  • Epoch-based (weekly) reward distribution.

  • Deposit and withdrawal of locked tokens, which influence the allocation of rewards.

  • Calculation and claiming of earned rewards for token owners.

  • Enforcement of whitelisting for new reward tokens to ensure controlled reward distribution.

  • Authorization checks that restrict certain actions (e.g., getReward and notifyRewardAmount) exclusively to ESCROW_VOTE_MANAGER.

By integrating with EscrowVoteManager and EscrowManager, the IncentiveRewardsDistributor ensures that reward distributions are fair, secure, and directly linked to voting power and locked tokens, aligning incentives with governance outcomes.


Inherited Contracts and Interfaces

  • IncentiveRewardsDistributor inherits from:

    • RewardsDistributor (abstract): Provides foundational logic for depositing/withdrawing votes, calculating earned rewards, notifying new rewards, and facilitating reward claims.

  • IIncentiveRewardsDistributor: Defines additional interfaces for getReward and notifyRewardAmount, integrating authorization and token whitelisting checks.

  • IRewardsDistributor: Interface specifying core reward distribution functions and data structures, which RewardsDistributor implements.

  • IEscrowVoteManagerV1, IEscrowManager: External interfaces providing information about ownership, voting power, and token whitelisting.


State Variables (Inherited from RewardsDistributor)

The IncentiveRewardsDistributor does not introduce new state variables. It relies entirely on those inherited from RewardsDistributor:

  • ESCROW_VOTE_MANAGER (address): The address of the escrow vote manager contract, which must authorize certain calls.

  • ESCROW_MANAGER (address): The address of the escrow manager contract, providing ownership data for tokens.

  • s_rewardTokens (address[]): Array of addresses of recognized reward tokens.

  • s_initialIncentiveTimestamp (uint256): The timestamp indicating when incentive distribution began.

  • s_totalSupplyByEpoch (mapping(uint256 => uint256)): The total amount of deposited (voted) tokens per epoch.

  • s_isRewardToken (mapping(address => bool)): Indicates whether a token is recognized as a reward token.

  • s_balanceByOwnerAndEpoch (mapping(address => mapping(uint256 => uint256))): Tracks each owner’s deposited token amount by epoch.

  • s_rewardAmountByTokenAndEpoch (mapping(address => mapping(uint256 => uint256))): The reward amount allocated for each token in each epoch.

  • s_lastRewardClaimByOwnerAndToken (mapping(address => mapping(address => uint256))): Records the last epoch timestamp when the owner claimed rewards for a given token.

All these variables are described in the RewardsDistributor documentation.


Constructor

Signature:

constructor(address escrowVoteManager_, address escrowManager_)

Description: Initializes the contract by calling the RewardsDistributor constructor with the escrow vote manager and escrow manager addresses. After construction, the contract is ready to handle reward-related operations based on the inherited logic.

Parameters:

  • escrowVoteManager_: Address of the escrow vote manager contract.

  • escrowManager_: Address of the escrow manager contract.


External Functions (IncentiveRewardsDistributor Specific)

getReward(...)

Signature:

function getReward(address owner_, address[] calldata rewardTokens_) 
    external 
    override (RewardsDistributor, IIncentiveRewardsDistributor) 
    nonReentrant

Description: Allows ESCROW_VOTE_MANAGER to claim rewards on behalf of a specified owner_ for a set of rewardTokens_. Only ESCROW_VOTE_MANAGER is authorized to call this function, ensuring that claims are directly tied to authorized voting operations and locked token states.

Parameters:

  • owner_: The address of the owner claiming rewards.

  • rewardTokens_: An array of reward token addresses to claim.

Checks:

  • msg.sender must be ESCROW_VOTE_MANAGER. Otherwise, UnauthorizedAccess() is thrown.

Effects:

  • Internally calls _getReward(owner_, rewardTokens_) from RewardsDistributor to calculate and distribute the earned rewards to the owner_.


notifyRewardAmount(...)

Signature:

function notifyRewardAmount(address rewardToken_, uint256 rewardAmount_) 
    external 
    override (RewardsDistributor, IIncentiveRewardsDistributor) 
    nonReentrant

Description: Notifies the contract of a new reward allocation for rewardToken_. If this token is not yet recognized as a reward token, this call checks whether the token is whitelisted via IEscrowVoteManagerV1(ESCROW_VOTE_MANAGER).s_isWhitelistedToken(rewardToken_). If not whitelisted, NotWhitelisted() is thrown. This ensures controlled introduction of new reward tokens.

Parameters:

  • rewardToken_: The address of the reward token being added.

  • rewardAmount_: The amount of the token to add as rewards.

Checks:

  • If rewardToken_ is not already in s_isRewardToken, checks if it is whitelisted.

  • rewardAmount_ must be non-zero.

Effects:

  • If new token recognized, it is added to s_rewardTokens and marked as a reward token.

  • Calls _notifyRewardAmount(msg.sender, rewardToken_, rewardAmount_) from RewardsDistributor to handle token transfer and epoch accounting.


Inherited External Functions (from RewardsDistributor)

The following functions are defined in IRewardsDistributor and implemented in RewardsDistributor. The IncentiveRewardsDistributor inherits them without modification:

deposit(...)

Signature:

function deposit(uint256 amount_, uint256 tokenId_) external

Description: Deposits an amount of β€œvoting power” (associated with a token ID) into the contract for the current epoch. Only ESCROW_VOTE_MANAGER can call this. This updates s_totalSupplyByEpoch and s_balanceByOwnerAndEpoch to reflect the deposited amount.

Parameters:

  • amount_: The amount of tokens (voting power) being deposited.

  • tokenId_: The token ID associated with this deposit.

Checks:

  • msg.sender must be ESCROW_VOTE_MANAGER. Otherwise, UnauthorizedAccess() is thrown.

Effects:

  • Increases s_totalSupplyByEpoch[currentEpochStart] and s_balanceByOwnerAndEpoch[ownerOf(tokenId_)][currentEpochStart] by amount_.

  • Emits TokensDeposited.


withdraw(...)

Signature:

function withdraw(uint256 amount_, uint256 tokenId_) external

Description: Withdraws previously deposited voting power from the current epoch, reducing the total supply and the owner’s balance for that epoch. Only ESCROW_VOTE_MANAGER can call this function.

Parameters:

  • amount_: The amount to withdraw.

  • tokenId_: The token ID associated with the withdrawal.

Checks:

  • msg.sender must be ESCROW_VOTE_MANAGER.

Effects:

  • Decreases s_totalSupplyByEpoch[currentEpochStart] and s_balanceByOwnerAndEpoch[ownerOf(tokenId_)][currentEpochStart] by amount_.

  • Emits TokensWithdrawn.


getRewardTokensCount()

Signature:

function getRewardTokensCount() external view returns (uint256)

Description: Returns the number of reward tokens currently recognized by the contract (the length of s_rewardTokens array).

Return:

  • uint256: The count of reward tokens.


earned(...)

Signature:

function earned(address owner_, address rewardToken_) external view returns (uint256, uint256)

Description: Calculates the total amount of rewards owner_ has earned for rewardToken_ since the last claim, iterating through past epochs up to a limit (52 epochs by default).

Parameters:

  • owner_: The address of the owner.

  • rewardToken_: The reward token to check.

Return:

  • (uint256 totalEarned, uint256 lastRewardClaimTimestamp): Total earned rewards and the updated timestamp after calculating earnings.


earnedByEpoch(...)

Signature:

function earnedByEpoch(address owner_, address rewardToken_, uint256 epoch_) external view returns (uint256)

Description: Calculates how many rewards owner_ earned for rewardToken_ during a specific epoch_.

Parameters:

  • owner_: Owner’s address.

  • rewardToken_: The reward token.

  • epoch_: The epoch start timestamp to check.

Return:

  • uint256: The amount of rewards earned in that specific epoch.


rewardPerToken(...)

Signature:

function rewardPerToken(address rewardToken_, uint256 epoch_) external view returns (uint256)

Description: Calculates the reward per token deposited for a given rewardToken_ in a specific epoch_. This is used in the calculation of each owner’s earned rewards by epoch.

Parameters:

  • rewardToken_: The reward token.

  • epoch_: The epoch start timestamp.

Return:

  • uint256: The reward per token amount for the epoch.


Internal Functions (from RewardsDistributor)

_getReward(owner_, rewardTokens_) and _notifyRewardAmount(sender_, rewardToken_, rewardAmount_) are internal functions in RewardsDistributor inherited by IncentiveRewardsDistributor:

  • _getReward(owner_, rewardTokens_): Iterates through the given reward tokens, calculates the earned amount using earned(...), updates the s_lastRewardClaimByOwnerAndToken mapping, and transfers the calculated rewards to owner_. Emits RewardsClaimed for each token.

  • _notifyRewardAmount(sender_, rewardToken_, rewardAmount_): Transfers rewardAmount_ of rewardToken_ from sender_ to the contract, updates s_rewardAmountByTokenAndEpoch[rewardToken_][currentEpochStart], sets s_initialIncentiveTimestamp if not set, and emits RewardNotified.

These internal functions are leveraged by IncentiveRewardsDistributor through getReward and notifyRewardAmount after performing authorization and whitelisting checks.


Events

Inherited from RewardsDistributor and IRewardsDistributor:

  • TokensDeposited: Emitted when tokens are deposited for a given tokenId.

  • TokensWithdrawn: Emitted when tokens are withdrawn.

  • RewardNotified: Emitted when a new reward amount is notified for an epoch.

  • RewardsClaimed: Emitted when an owner claims rewards.

IncentiveRewardsDistributor does not introduce additional events beyond these inherited ones.


Errors

From RewardsDistributor and IRewardsDistributor:

  • InvalidRewardToken()

  • UnauthorizedAccess()

  • ZeroAmountProvided()

  • NotWhitelisted()

IncentiveRewardsDistributor triggers UnauthorizedAccess() if getReward is called by anyone other than ESCROW_VOTE_MANAGER, and NotWhitelisted() if notifyRewardAmount is called with a token not previously recognized and not whitelisted.


Summary

IncentiveRewardsDistributor extends the RewardsDistributor by adding authorization and whitelisting checks for reward-related operations. It integrates seamlessly with the EYWA governance ecosystem, ensuring that rewards are distributed to token owners in proportion to their votes and locked tokens, while preventing unauthorized actions and distribution of unapproved reward tokens. This design maintains transparency, fairness, and security in the incentive allocation process.

Last updated