EmissionManagerV1
Overview
EmissionManagerV1 is an upgradeable contract that orchestrates weekly EYWA token emissions to various distribution streams, such as rebase rewards, gauge rewards, bonds, grants, and incentives. It integrates with the Escrow Manager to evaluate locked token balances and applies distinct emission formulas depending on whether the total locked tokens exceed a specified threshold. The contract also enforces constraints on weekly emissions, such as cooldown periods, maximum percentage increases, and valid distribution percentages.
Key Features:
Epoch-Based Emissions: Emissions occur in discrete one-week epochs, with a configurable weekly emission amount.
Distribution Percentages: Tokens are split among rebase rewards, bonds, grants, and incentives, each receiving a percentage of the weekly emission.
Threshold-Based Adjustments: If total locked tokens exceed a
s_lockThreshold
, alternate base rates and multipliers are applied to rebase calculations.Inflation Rates: Two inflation rates (
s_initialInflationRate
ands_secondaryInflationRate
) further influence the rebase portion of weekly emissions.Owner-Only Updates: Certain parameters, such as weekly emission amounts and distribution logic, can only be updated by the contract owner, subject to cooldowns and other constraints.
By implementing the IEmissionManagerV1
interface, EmissionManagerV1 provides a clear set of functionalities and events essential for managing the emission process in the EYWA ecosystem.
Inherited Contracts and Interfaces
UUPSUpgradeable (OpenZeppelin): Enables the contract to be upgradeable via a UUPS proxy pattern, ensuring only the owner can perform upgrades.
OwnableUpgradeable (OpenZeppelin): Provides ownership functionality, restricting sensitive actions (like parameter updates) to the owner.
IEmissionManagerV1: Interface declaring all essential methods (e.g.,
initialize
,updateEpoch
) and events for managing emissions.
Additional External References:
SafeERC20, IERC20 (OpenZeppelin): Used for secure ERC20 operations.
IEscrowVoteManagerV1: Receives gauge emission amounts and coordinates gauge reward distribution.
IEscrowManager: Provides total locked token data for rebase emission calculations.
ITreasury: Manages treasury funds from which weekly emissions are withdrawn.
IRebaseRewardsDistributorV1: Distributes rebase rewards and triggers relevant accounting updates.
Constants
EPOCH_DURATION: Duration of each emission epoch (1 week).
TOTAL_SUPPLY: Total EYWA token supply (1 billion).
MAXIMUM_EMISSION_INCREASE_PERCENTAGE: Maximum allowed percentage by which the weekly emission can increase, scaled by
PRECISION
.PRECISION: Scaling factor for percentage calculations (e.g., 100,000 means 100%).
EPOCH_COOLDOWN_PERIOD: Number of epochs required between emission state changes.
State Variables
Emission Parameters
s_currentWeeklyEmission (uint256)
: Current weekly emission amount in EYWA tokens.s_totalDistributedEmission (uint256)
: Accumulated amount of EYWA tokens distributed across all epochs.
Distribution Percentages
s_gaugeEmissionPercentage (uint256)
: Percent of weekly emission allocated to gauge rewards, scaled byPRECISION
.s_bondEmissionPercentage (uint256)
: Percent allocated to bond rewards, scaled byPRECISION
.s_grantEmissionPercentage (uint256)
: Percent allocated to grants, scaled byPRECISION
.s_incentiveEmissionPercentage (uint256)
: Percent allocated to incentives, scaled byPRECISION
.
Threshold and Rates
s_lockThreshold (uint256)
: The threshold of total locked tokens determining which emission formula to apply.s_baseRateBelowThreshold (uint256)
: Base rate for rebase emission if locked tokens <s_lockThreshold
.s_baseRateAboveThreshold (uint256)
: Base rate if locked tokens ≥s_lockThreshold
.s_rateMultiplierBelowThreshold (uint256)
: Rate multiplier if locked tokens <s_lockThreshold
.s_rateMultiplierAboveThreshold (uint256)
: Rate multiplier if locked tokens ≥s_lockThreshold
.
Inflation Rates
s_initialInflationRate (uint256)
: Inflation rate applied when locked tokens are below threshold.s_secondaryInflationRate (uint256)
: Inflation rate used when locked tokens are above threshold.
Epoch Management
s_currentEpochStart (uint256)
: Timestamp marking the start of the current emission epoch.s_lastChangeEpochStart (uint256)
: Timestamp marking the start of the epoch during the last emission state change (used for cooldown enforcement).s_epochCounter (uint256)
: Number of completed epochs.
Addresses
s_treasury (address)
: Address holding the EYWA tokens (treasury).s_rebaseRewardsDistributor (address)
: Distributor for rebase rewards.s_bondEmissionDistributor (address)
: Distributor for bond emissions.s_grantEmissionDistributor (address)
: Distributor for grant emissions.s_incentiveEmissionDistributor (address)
: Distributor for incentive emissions.s_escrowVoteManager (IEscrowVoteManagerV1)
: Escrow vote manager contract for gauge emissions.s_escrowManager (IEscrowManager)
: Escrow manager providing locked token data.s_eywa (IERC20)
: EYWA token used for emission distributions.
Constructor
Description: Disables contract initializers to prevent re-initialization in a UUPS proxy context.
External Functions
initialize(...)
initialize(...)
Description: Initializes the contract for the first time, setting the owner, treasury, emission distributors, and references to external managers/tokens. Configures initial weekly emission, distribution percentages, threshold-based rates, and inflation rates.
Parameters:
owner_
: Contract owner address.treasury_
: Address of treasury holding EYWA tokens.rebaseRewardsDistributor_
: Distributor contract for rebase rewards.bondEmissionDistributor_
: Distributor contract for bond rewards.grantEmissionDistributor_
: Distributor contract for grants.incentiveEmissionDistributor_
: Distributor contract for incentives.escrowVoteManager_
: The escrow vote manager contract instance.escrowManager_
: Escrow manager contract instance for locked token data.eywa_
: EYWA token contract.
Effects:
Calls
__UUPSUpgradeable_init()
and__Ownable_init(owner_)
.Sets initial values for emission rates, thresholds, and inflation parameters.
Marks the start of the current epoch.
updateTreasury(address newTreasury_)
updateTreasury(address newTreasury_)
Description: Updates the treasury address from which emissions are withdrawn.
Events:
Emits
TreasuryUpdated(newTreasury_)
.
updateEmissionDistributors(...)
updateEmissionDistributors(...)
Description: Updates the addresses for bond, grant, and incentive emission distributors. Only callable by the owner.
Parameters:
newBondEmissionDistributor_
: New bond emission distributor address.newGrantEmissionDistributor_
: New grant emission distributor address.newIncentiveEmissionDistributor_
: New incentive emission distributor address.
Events:
Emits
EmissionDistributorsUpdated
.
updateWeeklyEmissionState(...)
updateWeeklyEmissionState(...)
Description:
Adjusts the weekly emission amount and distribution percentages. Enforces a cooldown (EPOCH_COOLDOWN_PERIOD
) since the last change and forbids increases above the allowed percentage limit.
Checks & Constraints:
Must have at least 1 epoch (
s_epochCounter > 0
).Enforces cooldown:
block.timestamp
must be ≥s_lastChangeEpochStart + EPOCH_COOLDOWN_PERIOD * EPOCH_DURATION
.newWeeklyEmission_
must not exceed historical average timesMAXIMUM_EMISSION_INCREASE_PERCENTAGE / PRECISION
.Sum of new distribution percentages =
PRECISION
(100%).
Events:
Emits
WeeklyEmissionStateUpdated
.
updateParameters(...)
updateParameters(...)
Description: Updates threshold-based emission parameters, including base rates, rate multipliers, and inflation rates used in rebase calculations.
Events:
Emits
ParametersUpdated
with the updated values.
updateEpoch()
updateEpoch()
Description:
If a new epoch has started (block.timestamp >= s_currentEpochStart + EPOCH_DURATION
), the contract calculates distributions for the new week and transfers tokens to the various distributors.
Logic:
Withdraws
s_currentWeeklyEmission
froms_treasury
.Calculates rebase emission portion with
_calculateRebaseEmission
.Sends rebase emission to the rebase rewards distributor and calls
checkpoint()
.Distributes leftover among gauge, bond, grant, and incentive streams proportionally.
Increments
s_epochCounter
and updatess_totalDistributedEmission
.
Events:
Emits
EpochUpdated
with detailed breakdown.
averageWeeklyEmissionOverTime()
averageWeeklyEmissionOverTime()
Description:
Returns the average weekly emission across all completed epochs:
s_totalDistributedEmission / s_epochCounter
.
Internal and Private Functions
_authorizeUpgrade(address)
_authorizeUpgrade(address)
Description: Restricts the UUPS upgrade function to the contract owner.
_calculateRebaseEmission(uint256 currentWeeklyEmission_)
_calculateRebaseEmission(uint256 currentWeeklyEmission_)
Description:
Derives the rebase portion of the weekly emission based on total locked tokens from s_escrowManager
.
If
m_totalLocked >= s_lockThreshold
, uses one set of base rates, multipliers, ands_secondaryInflationRate
.Otherwise, uses another set and
s_initialInflationRate
.
Return:
rebaseEmission_
: The final rebase token amount.
Formula Components:
Computes an adjustment factor that depends on
s_baseRateAboveThreshold
/s_rateMultiplierAboveThreshold
ors_baseRateBelowThreshold
/s_rateMultiplierBelowThreshold
.Adds an inflation portion scaled by either
s_secondaryInflationRate
ors_initialInflationRate
.Divides by
1e18
at the end to restore integer arithmetic precision.
Events
TreasuryUpdated(address newTreasury)
EmissionDistributorsUpdated(address newBondEmissionDistributor, address newGrantEmissionDistributor, address newIncentiveEmissionDistributor)
WeeklyEmissionStateUpdated(uint256 newWeeklyEmission, uint256 newGaugeEmissionPercentage, ..., uint256 newIncentiveEmissionPercentage)
ParametersUpdated(..., uint256 initialInflationRate, uint256 secondaryInflationRate)
EpochUpdated(uint256 epochStartTimestamp, uint256 totalEmission, uint256 rebaseEmission, ..., uint256 incentiveEmission)
These events log critical changes such as treasury updates, changes to emission distribution, parameter updates, and epoch transitions.
Errors
InvalidCallee()
: Thrown if an unauthorized entity calls certain functions (not used in current logic).ZeroEpochCounter()
: Thrown ifupdateWeeklyEmissionState
is called before any epoch has elapsed.CooldownPeriodNotElapsed()
: Thrown if a new weekly emission state update is attempted within the cooldown period.ExcessiveEmissionIncrease()
: Thrown if the new weekly emission exceeds the allowed maximum over historical average.InvalidPercentagesSum()
: Thrown if the sum of new distribution percentages does not equalPRECISION
(100%).
Summary
EmissionManagerV1 is a flexible and upgradeable contract for distributing EYWA tokens weekly to different reward mechanisms—governed by configurable rates and distribution percentages. By leveraging a threshold-based logic, it dynamically adjusts rebase emissions based on the total locked tokens, ensuring that ecosystem participation and inflation rates are balanced. It integrates seamlessly with treasury, escrow, and reward distributor contracts to enforce cooldowns, respect maximum emission growth, and emit relevant events detailing emission updates.
Last updated