RebaseRewardsDistributorV1
Overview
RebaseRewardsDistributorV1 is a contract designed to distribute βrebaseβ rewards to veEYWA token holders over time. It integrates with the escrow manager, which handles locked veEYWA tokens, and the emission manager, which determines the emission epochs. The contract aims to:
Distribute EYWA token rewards proportionally to the voting power (veEYWA balance) of each token over weekly epochs.
Update and record reward distributions at checkpoints to ensure accurate and time-aligned allocations.
Allow token holders to claim their accumulated rewards at any time.
Automatically deposit claimed rewards into the corresponding lock if it is still active, or transfer them directly to the owner if the lock is expired.
Key Features:
Epoch-Based Distribution: Rewards are distributed on a weekly basis (1 week per epoch).
Checkpoints: The contract records reward distributions at checkpoints. Each checkpoint corresponds to changes in reward balances over time.
Claiming Rewards: Holders of veEYWA tokens can claim their accrued rewards. If the associated lock is active, claimed rewards are added to that lock. Otherwise, rewards are transferred directly to the lock owner.
Integration with Ecosystem Contracts: The contract relies on
IEscrowManager
for lock status and voting power data, and onIEmissionManagerV1
for ensuring up-to-date emission periods before claims.
Inherited Contracts and Interfaces
UUPSUpgradeable (OpenZeppelin): Provides upgradeability using the UUPS proxy standard.
OwnableUpgradeable (OpenZeppelin): Enables ownership functionalities, restricting certain operations (like upgrades) to the owner.
IRebaseRewardsDistributorV1: Defines the interface for initialization, checkpointing, claiming rewards, and calculating earned amounts.
Additional External References:
SafeERC20, IERC20 (OpenZeppelin): For safely handling ERC20 token transfers.
Math (OpenZeppelin): Provides mathematical utilities.
IEscrowManager: Provides data about veEYWA locks, including unlock times, voting power history, and token ownership.
IEmissionManagerV1: Ensures that the emission period is updated before rewards can be claimed.
Constants
EPOCH_DURATION
EPOCH_DURATION
Type:
uint256
Value:
1 weeks
Description: Duration of each emission and reward distribution epoch, aligning all calculations to weekly intervals.
State Variables
s_rewardsStartTime
Type:
uint256
Description: The timestamp at which reward distribution starts. Aligned to an epoch boundary.
s_lastCheckpointTime
Type:
uint256
Description: The timestamp of the last recorded checkpoint. Used for distributing rewards proportionally over elapsed time.
s_previousTokenBalance
Type:
uint256
Description: The EYWA token balance of this contract at the last checkpoint, used to calculate newly added rewards since the last checkpoint.
s_eywa
Type:
IERC20
Description: The EYWA token contract used for distributing rebase rewards.
s_escrowManager
Type:
IEscrowManager
Description: Reference to the escrow manager that manages veEYWA locks and provides data on voting power, ownership, and lock status.
s_emissionManager
Type:
IEmissionManagerV1
Description: Reference to the emission manager contract which controls weekly emissions. It must update emission periods before claims are processed.
s_weeklyTokensDistributed
Type:
uint256[1000000000000000]
Description: Large static array mapping from a weekly timestamp (epoch start) to the amount of tokens distributed that week. This allows calculating how many tokens were allocated in each epoch.
s_lastClaimedTimeByTokenId
Type:
mapping(uint256 => uint256)
Description: Tracks the last claimed timestamp for each veEYWA token ID. Used to calculate how many weeks of rewards remain unclaimed.
Constructor
constructor()
Description: Disables initializers to prevent re-initialization of this upgradeable contract.
External Functions
initialize(...)
initialize(...)
Signature:
Description:
Initializes the contract state. Sets the owner, references to EYWA token, escrow manager, and emission manager. Aligns s_rewardsStartTime
and s_lastCheckpointTime
to epoch boundaries and approves the escrow manager to transfer unlimited EYWA tokens on behalf of this contract.
Parameters:
owner_
: Address of the contract owner.eywa_
: The EYWA token contract.escrowManager_
: The escrow manager contract reference.emissionManager_
: The emission manager contract reference.
Effects:
Calls
__UUPSUpgradeable_init()
and__Ownable_init(owner_)
.Sets
s_rewardsStartTime
ands_lastCheckpointTime
to the nearest epoch boundary (current time truncated to multiple ofEPOCH_DURATION
).Approves the escrow manager for EYWA token transfers.
checkpoint()
checkpoint()
Signature:
Description:
Records a new checkpoint to distribute rewards proportional to the time elapsed since the last checkpoint. Only callable by the emission manager contract. This function calculates how many new tokens were added since the last checkpoint and allocates them to the appropriate weeks in s_weeklyTokensDistributed
.
Checks:
msg.sender
must beaddress(s_emissionManager)
, otherwiseUnauthorizedCaller()
is thrown.
Effects:
Updates
s_weeklyTokensDistributed
for each relevant week, proportionally distributing newly added tokens over the elapsed time.Updates
s_previousTokenBalance
ands_lastCheckpointTime
.Emits
Checkpoint
event.
claim(uint256 tokenId_)
claim(uint256 tokenId_)
Signature:
Description: Claims all accrued rewards for a specific veEYWA token ID. Before claiming, checks that the emission period is updated. The earned rewards are determined by calculating the tokenβs voting power over each unclaimed epoch and the total tokens distributed. If the lock is active, rewards are deposited into that lock via the escrow manager. If the lock is expired, tokens are transferred directly to the lockβs last owner.
Parameters:
tokenId_
: The veEYWA token ID for which to claim rewards.
Checks:
s_emissionManager.s_currentEpochStart()
must not be less than the current epoch (determined byblock.timestamp / EPOCH_DURATION * EPOCH_DURATION
), otherwiseEmissionPeriodNotUpdated()
is thrown.
Effects:
Calls the internal
_claim
function to calculate and distribute rewards.Updates
s_previousTokenBalance
by subtracting the claimed amount.Emits
RewardsClaimed
event if rewards are claimed.
claim(uint256[] calldata tokenIds_)
claim(uint256[] calldata tokenIds_)
Signature:
Description:
Claims rewards for multiple veEYWA token IDs in a single transaction. The same checks, logic, and effects as claim(uint256 tokenId_)
are applied to each token ID in the array.
Parameters:
tokenIds_
: Array of token IDs for which to claim rewards.
Checks:
Same emission period check as single claim.
Effects:
Iterates through each
tokenId_
, calling_claim
internally.Aggregates the total claimed rewards and subtracts from
s_previousTokenBalance
.Emits a
RewardsClaimed
event for each token ID that has rewards.
earned(uint256 tokenId_)
earned(uint256 tokenId_)
Signature:
Description:
View function to calculate how many rewards a given tokenId_
would earn if claimed at the current moment, without actually claiming them.
Parameters:
tokenId_
: The veEYWA token ID to check.
Return:
uint256
: The amount of unclaimed rewards earned bytokenId_
.
Logic:
Calls the internal
_earned
function to compute the reward based on weekly distributions and voting power history.
Internal Functions
_checkpoint()
_checkpoint()
Signature:
Description:
Called by checkpoint()
to handle the logic of distributing newly observed tokens since the last checkpoint over the elapsed time. Divides the distribution proportionally among weeks that passed.
Logic:
Compute
m_totalReward
=balanceOf(this)
-s_previousTokenBalance
.Spread
m_totalReward
across each relevant epoch interval proportionally to the elapsed time.Update
s_weeklyTokensDistributed
accordingly.
Effects:
Updates
s_previousTokenBalance
ands_lastCheckpointTime
.Emits
Checkpoint
.
_claim(uint256 tokenId_, uint256 lastCheckpointTime_)
_claim(uint256 tokenId_, uint256 lastCheckpointTime_)
Signature:
Description:
Handles the logic of claiming rewards for a single token ID. It calls _earned
to compute how many tokens the ID is owed, updates s_lastClaimedTimeByTokenId
, and returns the reward amount.
Parameters:
tokenId_
: The veEYWA token ID to claim for.lastCheckpointTime_
: The truncated last checkpoint time.
Return:
uint256
: The amount of claimed rewards.
Effects:
Updates
s_lastClaimedTimeByTokenId[tokenId_]
.Emits
RewardsClaimed
ifm_reward > 0
.
_earned(uint256 tokenId_, uint256 lastCheckpointTime_)
_earned(uint256 tokenId_, uint256 lastCheckpointTime_)
Signature:
Description:
Calculates how many rewards a token ID earned between s_lastClaimedTimeByTokenId[tokenId_]
and lastCheckpointTime_
. It iterates up to 52 epochs backward, retrieving voting power and total supply data from s_escrowManager
, and sums the proportional share of s_weeklyTokensDistributed
for each epoch.
Parameters:
tokenId_
: The veEYWA token ID to calculate earnings for.lastCheckpointTime_
: Reference time for calculation (truncated to epoch boundary).
Return:
(uint256 m_reward, uint256 m_initialWeekCursor, uint256 m_updatedWeekCursor)
:m_reward
: total calculated rewards.m_initialWeekCursor
: starting epoch for the calculation.m_updatedWeekCursor
: ending epoch after calculation.
Logic:
Determines the initial claiming week from
s_lastClaimedTimeByTokenId[tokenId_]
.For each week until
lastCheckpointTime_
or up to 52 weeks, calculates the ratio of the tokenβs past voting power to the total supply and multiplies by that weekβs distributed tokens.Accumulates
m_reward
accordingly.
Events
Checkpoint
Checkpoint
Emitted When: A new checkpoint is recorded distributing tokens over elapsed time since the last checkpoint.
Parameters:
timestamp
: The time at which the checkpoint was made.totalReward
: The total new reward observed since the last checkpoint.
RewardsClaimed
RewardsClaimed
Emitted When: A token ID claims its accrued rewards.
Parameters:
tokenId
: The veEYWA token ID claiming rewards.initialWeekCursor
: The starting epoch of reward accumulation.updatedWeekCursor
: The ending epoch after calculating earned rewards.reward
: Amount of reward claimed.
Errors
UnauthorizedCaller()
: Thrown if a restricted function likecheckpoint()
is called by an unauthorized entity.EmissionPeriodNotUpdated()
: Thrown ifclaim()
is attempted before the emission manager has updated the emission period for the current epoch.
Summary
RebaseRewardsDistributorV1 manages weekly reward distributions for veEYWA token holders. By creating checkpoints, tracking newly added tokens, and storing how many tokens were distributed each week, it allows for fair and accurate calculation of accrued rewards. The contract ensures that claims only occur after emission periods are up-to-date and properly accounts for active versus expired locks when distributing claimed rewards. This structure fosters a stable and incentive-aligned environment for participants in the EYWA ecosystem.
Last updated