Skip to main content

Emissions Controller (Hub)

The Emissions Controller only exists on the Astroport Governance Hub (Neutron) and allows vxASTRO holders to vote on ASTRO emissions. This Hub's contract is responsible for collecting/validating votes from vxASTRO stakers from all outposts and calculating the final ASTRO emissions every epoch.

Voting With vxASTRO

In order to participate in emission voting, you will need vxASTRO. Holders of vxASTRO may vote for whitelisted pools once every epoch. After submission, votes cannot be changed until the next epoch has begun. A new epoch will take place every 2 weeks (on Monday 00:00 UTC starting from Mon Oct 28 2024). If you do not vote in the current epoch but had voted in the previous epoch, then your previous vote will remain intact.

[!NOTE] You do not need to revote every epoch if you intend to vote for the same pools with the same weight ratio.

Example transaction message:


{
"vote": {
"votes": [
[
"neutron1sc470v7me3gmjnqmpgvc7cnus2ge7dcj05q6l2xvc0zcredh42estrhgnw", // LP token address 1
"0.5" // Pool 1 weight
],
[
"neutron1799j4qcwqnrl4mdu4ryjkpdpqwjdjjj7x5tjc5swwfq3faqd7lrsdn659k", // LP token address 2
"0.3" // Pool 2 weight
],
[
"neutron1vpvhl7j5ecs7fjr0mgqr0qcf4sn6g9vtewx4ex44lg4s8px07lfse4dy0w", // LP token address 3
"0.2" // Pool 3 weight
]
]
}
}

  • The executable message accepts an array of tuples with LP token and vote weight.
  • Vote weight is a number between 0 and 1 and total vote weight can't exceed 1.

Pool Whitelisting

The Emissions Controller accepts votes only for whitelisted pools. Whitelisting a pool is permissionless but requires an ASTRO fee to be paid (initially 1500 ASTRO) that is set by governance. Anyone can whitelist a pool that is registered on that outpost. The Hub contract will also confirm that the specified LP token corresponds to the pool in the factory.

vxASTRO Amount Changes

If a user locks additional vxASTRO or unlocks the amount, the changes are then reflected in the Emissions Controller. The contract updates their voting power based on their previous weight distribution.

For example, user with 100 voting power voted [(pool1, 0.5), (pool2, 0.5)]. Their initial contribution would be 50 to pool1 and 50 to pool2. If they lock 100 more vxASTRO, their new voting power would be 200 and their contribution to pool1 and pool2 would be 100 each. If a user requests to unlock their vxASTRO, their total vote contribution will be removed from both pools.

ASTRO Dynamic Emissions Curve

Total ASTRO emissions are derived every epoch based on the two-epoch Exponential Moving Average (EMA) of the total ASTRO collected to the ASTRO staking contract (i.e. ASTRO buybacks). This two-epoch EMA is calculated by the following formula:


(V_n-1 * 2/ 3 + EMA_n-1 * 1/ 3)

  • V_n is the collected ASTRO amount at epoch n
  • n is the current epoch

The dynamic emissions formula is:


next emissions = MAX(MIN(max_astro, V_n-1 * emissions_multiple), MIN(max_astro, two-epochs EMA))

  • max_astro is the cap or upper limit of emissions (initially 1.4M ASTRO)
  • emissions_multiple is the constant that controls the ASTRO inflation rate (initially 0.8)
  • max_astro and emissions_multiple part of the contract state and can be modified by governance

Since this formula is recursive, the contract requires accurate EMA and collected ASTRO values from the previous epoch in order to calculate the next epoch's emissions.

Emissions Distribution / "Tuning"

We call the process of ASTRO emission distribution tuning. The tuning endpoint is permissionless and has a 2-week cooldown.

During the tuning process, the contract queries snapshotted votes per pool at the exact start of the epoch and determines the total voting power. It then filters out pools which are not part of any outpost and/or whitelisted and sorts these pools by votes to determine the top X pools. At the same time as this endpoint is executed, new dynamic ASTRO emissions are calculated.


X = 'config.pools_per_outpost' * number of outposts

  • config.pools_per_outpost is a constant set by governance (initially 5)

The contract distributes ASTRO to the selected pools based on their percentage share of total voting power of selected pools from the previous step. Based on whether the outpost is the Hub or remote Astroport deployment, the contract sends ASTRO along with an executable message to the Astroport Incentives contract, or IBC Hook to remote Emissions Controller, respectively.

[!NOTE] The receiving outpost must implement IBC hooks to have the whole process working in one go. Astroport currently has one outpost (Sei network) that does not support it. This one outpost requires manual intervention by Builders multisig until it support is added.

In the diagram below, several scenarios are presented. Black arrows represent the flow on the Hub, green arrows represent successful IBC transfer to the remote outpost with possible filtered invalid LP tokens, red arrows represent failed IBC transfer to the remote outpost followed by permissionless retry_failed_outposts call.

ASTRO Pools

Each outpost may or may not have an ASTRO pool which needs to be incentivized with flat emissions. Those pools cannot be voted on, and they receive emissions out of the dynamic emissions curve by default. This is to incentivise sufficient ASTRO liquidity for swapping rewards on each outpost.

Governance Voting (xASTRO / Astral Assembly)

vxASTRO stakers have voting power equal to their xASTRO staked amount. When someone submits a new governance proposal in the Assembly contract, the Emissions Controller Hub is responsible for registering it on all outposts. Once registered, vxASTRO outpost stakers can then vote on it. The Emissions Controller receives IBC messages from each Emissions Controller (Outpost) and applies votes in the Assembly contract.

Maintaining Whitelist Presence

In order to increase security and prevent whitelist "spam" a special parameter has been introduced: config.whitelist_threshold (initially 0.001 or 0.1% of all votes). Every epoch during tuning this contract removes all pools that have less than config.whitelist_threshold of total votes. Those pools will need to be whitelisted again, and their voting process starts from scratch. Users who voted for removed pools will need to vote again or re-apply their votes via the special refresh_user_votes endpoint with no cooldown. Whitelisted pools that receive an amount of total votes that are above this parameter will remain whitelisted.

Emissions Controller Hub Balance

Astroport governance must maintain this contract's ASTRO and NTRN balance. ASTRO is used for emission distribution and NTRN is used for IBC fees. It is expected that governance will top up the contract with ASTRO upfront for the first year. At the time of writing, Neutron requires 0.2 NTRN per IBC transfer while 0.1 out of 0.2 is sent back to the contract. So generally, it is expected that the contract should have 0.2 * number of outposts NTRN balance every epoch.

IBC Failures

Thanks to Neutron Integrated Apps support, it allows handling of timeouts and failures of ICS20 packets. After the tuning process, IBC callbacks are processed to check that each outpost is marked as done or failed depending on the result. If an outpost has failed this check, then anyone can call the retry_failed_outposts endpoint to retry all failed outposts. If an outpost has failed the check and is not retried during the epoch, then their state will be cleared on the next epoch.