rewards

package
v3.1.7-near-hf Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 15, 2024 License: Apache-2.0 Imports: 23 Imported by: 0

README

x/rewards

Abstract

This document specifies the rewards module of Lava Protocol.

The rewards module is responsible for distributing rewards to validators and providers. Rewards are collected from the validators' and providers' pools, respectively. The pools' funds originate from the treasury account - a module account that holds all the pre-allocated Lava tokens of the network. It is important to note that the pre-allocated amount is constant, and there will be no minting of new Lava tokens in the future.

The rewards module also operates the Incentivized Providers RPC program (IPRPC). This program distributes bonus rewards to providers servicing specific chains. The IPRPC rewards are funded by the chains' DAO and other contributors.

Please note that this module replaces Cosmos SDK's mint module, which is typically responsible for minting rewards for validators.

Contents

Concepts

The Treasury

As per Lava's vision, there is a constant supply of Lava tokens from the chain's genesis. There will be no minting of new tokens in the future like other Cosmos-SDK based chains. The treasury account holds all of Lava's pre-allocated tokens. The total amount of coins will be $10^9 * 10^6$ ulava.

Rewards Pools

The rewards module is responsible on distributing rewards for validators that create new blocks, and providers that provide RPC service for their consumers.

To manage the rewards, the module uses two rewards pools: allocation pools and distribution pools. Note that there are two allocation pools and two distribution pools to manage the validators and providers rewards independently.

The allocation pools get some of the treasury account's tokens and hold onto it. Once a month, the allocation pools transfer a fixed amount of funds to the distribution pools. This monthly transfer will last for 4 years, after which the allocation pools' funds will be depleted (the allocation pools lifetime (4 years) is a pre-defined constant in the module's code). Note that before the allocation pools transfer the funds, the distribution pools' tokens are burned according to the LeftOverBurnRate parameter (see below).

The distribution pools use the monthly quota of funds to distribute rewards for validators and providers.

Validators Rewards Pool

In Cosmos-SDK chains, validators get rewards for creating blocks by the Cosmos' distribution module. For each new block, new tokens are minted and distributed to all the accounts that contributed to the new block creation.

In Lava, the Cosmos validators reward distribution mechanism remains as is, but the source of the tokens comes from the rewards module (and not the mint module). As stated above, the rewards are managed using two pools: an allocation pool and a distribution pool.

The allocation pool of validators, validators_rewards_allocation_pool, gets 3% of the tokens of the treasury account.

The distribution pool of validators, validators_rewards_distribution_pool, uses its funds to reward validators for proposing new blocks. Same as Cosmos' mint module, the validators_rewards_distribution_pool transfers the block rewards to the fee collection account which is used by Cosmos' distribution module to reward the validators.

The validators block reward is calculated using the following formula:

Reward = \frac{{\text{{validators\_distribution\_pool\_balance}}} \cdot {\text{bonded\_target\_factor}}}{\text{{remaining\_blocks\_until\_next\_emission}}}

Where:

  • $\text{validators\_distribution\_pool\_balance}$ - The remaining balance in the validators_rewards_distribution_pool.
  • $\text{bonded\_target\_factor}$ - A factor calculated with the module's params (see below).
  • $\text{remaining\_blocks\_until\_next\_emission}$ - The amount of blocks until the next monthly refill of the validators_rewards_distribution_pool.
Providers Rewards Pool

Providers get rewards for their services from the funds used to buy subscriptions (see subscription module readme).

Besides these rewards, the provider also get monthly bonus rewards from a pre-allocated rewards pools. To manage this, like the validators, the providers have an allocation and distribution rewards pools. The bonus rewards exist to provide additional rewards when there is no much demand (few subscriptions).

The total monthly bonus rewards ("total spec payout") are calculated per spec by the following formula:

\text{Total spec payout}=\\\min\{MaxRewardsBoost\cdot\text{Total Base Payouts}, \\ \text{Spec Payout Cap}, \\ \max\{0,1.5(\text{Spec Payout Cap})-0.5(\text{Total Base Payouts})\}\}

Where:

  • $\text{MaxRewardsBoost}$ - A module's parameter (see below).
  • $\text{Total Base Payouts}$ - The sum of all base payouts the providers for this spec collected = $\sum_{provider_1.._n} (\text{{provider base rewards}}_i)$
  • $\text{Spec Payout Cap}$ - The max value for this spec bonus rewards = $\frac{specStake\cdot specShares}{\sum_i{specStake \cdot specShares}_i}$.
  • SpecStake = Total effective stake of providers in this spec.
  • SpecShares = Weight factor for the spec (determined in each spec)

The total spec payout is distributed between providers proportional to the rewards they collected from subscriptions throughout the month. Each provider will get bonus rewards according to the following formula:

Provider Bonus Rewards = Total Spec Payout \cdot \frac{\sum_{\text{payment} \; i} (\text{{provider base rewards}}_{i,j} \times \text{{adjustment}}_{i,j})}{\sum_{\text{provider}\;j'}\sum_{\text{payment} \; i}  (\text{{provider base rewards}}_{i,j'}  )}

Note that some of the providers rewards are sent to the community pool (according to the CommunityTax parameter, determined by the distribution module) and to the validators block rewards (according to the ValidatorsSubscriptionParticipation parameter, see below). For more details about the adjustment, see below.

The participation fees are calculated according to the following formulas:

\text{Validators Participation Fee} = \frac{ValidatorsSubscriptionParticipation}{1-CommunityTax}
\text{Community Participation Fee} = ValidatorsSubscriptionParticipation + CommunityTax\\ - \text{Validators Participation Fee}
Adjustment

Adjustment is a security mechanism that prevents collusion and abuse of rewards boost. It calculates the distribution of usage across multiple providers for each consumer. The more scattered a consumer's usage is across providers, the higher the bonus rewards they can receive. The adjustment value is always smaller or equal to one and can reduce the bonus rewards by up to $\frac{1}{MaxRewardsBoost}$.

The adjustment is calculated per epoch using a weighted average based on usage. It considers the consumer's CU (compute units) used with a specific provider relative to the total CU the consumer used. The formula is as follows:

\text{epochAdjustment}_\text{consumet i, provider j}=\\\min\{1,\;\;\;minAdjustment\cdot(\frac{\sum_{\text{provider }k}{CU_\text{i,k}}}{CU _\text{i,j}})\}
\text{monthlyAdjustment}_{i,k} = \frac{\sum_{\text{epoch}\; t }\left(CU_\text{i}(t)\cdot \text{epochAdjustment}_{i,k}(t)\right)}{\sum_{\text{epoch}\; t}CU_{i}(t)}
IPRPC

IPRPC (Incentivized Providers RPC) is a program designed to motivate providers to offer services for specific chains using Lava. Providers supplying RPC data for chain X will receive additional rewards from the IPRPC pool each month. This pool is funded by chain X's DAO and other contributors.

The IPRPC pools will hold both Lava's native tokens and IBC wrapped tokens. Providers' rewards will be based on the amount of CU they serviced during the month relative to other providers' serviced CU. Only the CU from eligible subscriptions will be counted. IPRPC eligible subscriptions are determined via a government proposal.

Users have the freedom to fund the pool with any token of their choice, for any supported chain and set the emission schedule for their funds. For instance, a user can fund the IPRPC pool for the Osmosis chain with 300ulava, which will be dispersed over a period of three months. It's important to note that the IPRPC pool will start receiving funds from the beginning of the upcoming month.

In order to fund the IPRPC pool, the user's funds must cover the monthly minimum IPRPC cost, a parameter determined by governance. This minimum IPRPC cost will be subtracted from the monthly emission.

Parameters

The rewards module contains the following parameters:

Key Type Default Value
MinBondedTarget math.LegacyDec 0.6
MaxBondedTarget math.LegacyDec 0.8
LowFactor math.LegacyDec 0.5
LeftOverBurnRate math.LegacyDec 1
MaxRewardsBoost uint64 5
ValidatorsSubscriptionParticipation math.LegacyDec 0.05
MinBondedTarget

MinBondedTarget is used to calculate the BondedTargetFactor. This is the percentage of stake vs token supply that above it, reduction in validators block rewards is done.

MaxBondedTarget

MaxBondedTarget is used to calculate the BondedTargetFactor. This is the percentage in which the validators block rewards reduction is capped and reaches LowFactor.

LowFactor

LowFactor is used to calculate the BondedTargetFactor. This is the linear reduction rate/slope of the validators block rewards.

LeftOverBurnRate

LeftOverBurnRate determines the percentage of tokens to burn before refilling the distribution rewards pool with the monthly quota (from the allocation pool). LeftOverBurnRate = 0 means there is no burn.

BondedTargetFactor

In Lava we wanted to make validator rewards decrease linearly with the increase in stake. The BondedTargetFactor encapsulates this behaviour.

To calculate the BondedTargetFactor see the following formula (note that the staking module's BondedRatio parameter is used, which is the fraction of the staking tokens which are currently bonded):

\text{BondedTargetFactor}= \\\begin{cases}
1 & \text{$\text{BondRatio} < \text{MinBonded}$}\\
\frac{\text{MaxBonded}-\text{BondRatio}}{\text{MaxBonded}-\text{MinBonded}} + (\text{LowFactor})\frac{\text{BondRatio}-\text{MinBonded}}{\text{MaxBonded}-\text{MinBonded}}  & \text{$\text{MinBonded} < \text{BondRatio} < \text{MaxBonded}$}\\
\text{LowFactor} & \text{$\text{BondRatio} > \text{MaxBonded}$}\\
\end{cases}
MaxRewardsBoost

MaxRewardsBoost is a multiplier that determines the maximum bonus for provider rewards from subscriptions.

ValidatorsSubscriptionParticipation

ValidatorsSubscriptionParticipation is used to calculate the providers rewards participation fees.

Queries

The rewards module supports the following queries:

Query Arguments What it does
block-reward none show the block reward for validators
pools none show the info of the distribution pools
params none shows the module's parameters
show-iprpc-data none shows the IPRPC data that includes the minimum IPRPC cost and a list of IPRPC eligible subscriptions
iprpc-provider-reward provider (string) shows the estimated IPRPC rewards for a specific provider (relative to its serviced CU) for the upcoming monthly emission
iprpc-spec-rewards spec (string, optional) shows a specific spec's IPRPC rewards (for the entire period). If no spec is given, all IPRPC rewards are shown

Note, use the provider's address for the iprpc-provider-reward query. For more information on the provider's two addresses (regular and vault) see the epochstorage module's README.md.

Transactions

All the transactions below require setting the --from flag and gas related flags.

The rewards module supports the following transactions:

Transaction Arguments What it does
fund-iprpc spec (string), duration (uint64, in months), coins (sdk.Coins, for example: 100ulava,50ibctoken) fund the IPRPC pool to a specific spec with ulava or IBC wrapped tokens. The tokens will be vested for duration months.

Please note that the coins specified in the fund-iprpc transaction is the monthly emission fund. For instance, if you specify a fund of 100ulava for a duration of three months, providers will receive 100ulava each month, not 33ulava.

Also, the coins must include duration*min_iprpc_cost of ulava tokens (min_iprpc_cost is shown with the show-iprpc-data query).

Proposals

The rewards module supports the set-iprpc-data proposal which set the minimum IPRPC cost and the IPRPC eligible subscriptions.

To send a proposal and vote use the following commands:

lavad tx gov submit-legacy-proposal set-iprpc-data <deposit> --min-cost 0ulava --add-subscriptions addr1,addr2 --remove-subscriptions addr3,addr4 --from alice <gas-flags>

lavad tx gov vote <latest_proposal_id> yes --from alice <gas-flags>

Events

The rewards module has the following events:

Event When it happens
distribution_pools_refill a successful distribution rewards pools refill
provider_bonus_rewards a successful distribution of provider bonus rewards
iprpc_pool_emmission a successful distribution of IPRPC bonus rewards
iprpc_pool_emmission a successful distribution of IPRPC bonus rewards
set_iprpc_data a successful setting of IPRPC data
fund_iprpc a successful funding of the IPRPC pool
transfer_iprpc_reward_to_next_month a successful transfer of the current month's IPRPC reward to the next month. Happens when there are no providers eligible for IPRPC rewards in the current month
provider_reward a successful reward transfer to a provider
delegator_reward a successful reward transfer to a delegator

Note, providers and their delegators get rewards for several reasons: subscription rewards (relay payments), providers bonus rewards and IPRPC rewards. Those reasons and additional information are included in the provider_reward and delegator_reward events.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BeginBlocker

func BeginBlocker(ctx sdk.Context, k keeper.Keeper)

BeginBlocker calculates the validators block rewards and transfers them to the fee collector

func ExportGenesis

func ExportGenesis(ctx sdk.Context, k keeper.Keeper) *types.GenesisState

ExportGenesis returns the capability module's exported genesis.

func InitGenesis

func InitGenesis(ctx sdk.Context, k keeper.Keeper, genState types.GenesisState)

InitGenesis initializes the capability module's state from a provided genesis state.

func NewHandler

func NewHandler(k keeper.Keeper) sdk.Handler

NewHandler ...

Types

type AppModule

type AppModule struct {
	AppModuleBasic
	// contains filtered or unexported fields
}

AppModule implements the AppModule interface for the capability module.

func NewAppModule

func NewAppModule(
	cdc codec.Codec,
	keeper keeper.Keeper,
	accountKeeper types.AccountKeeper,
	bankKeeper types.BankKeeper,
) AppModule

func (AppModule) BeginBlock

func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock)

BeginBlock executes all ABCI BeginBlock logic respective to the capability module.

func (AppModule) ConsensusVersion

func (AppModule) ConsensusVersion() uint64

ConsensusVersion implements ConsensusVersion.

func (AppModule) EndBlock

EndBlock executes all ABCI EndBlock logic respective to the capability module. It returns no validator updates.

func (AppModule) ExportGenesis

func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage

ExportGenesis returns the capability module's exported genesis state as raw JSON bytes.

func (AppModule) GenerateGenesisState

func (AppModule) GenerateGenesisState(simState *module.SimulationState)

GenerateGenesisState creates a randomized GenState of the module

func (AppModule) InitGenesis

func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate

InitGenesis performs the capability module's genesis initialization It returns no validator updates.

func (AppModule) Name

func (am AppModule) Name() string

Name returns the capability module's name.

func (AppModule) ProposalContents

ProposalContents doesn't return any content functions for governance proposals

func (AppModule) RegisterInvariants

func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry)

RegisterInvariants registers the capability module's invariants.

func (AppModule) RegisterServices

func (am AppModule) RegisterServices(cfg module.Configurator)

RegisterServices registers a GRPC query service to respond to the module-specific GRPC queries.

func (AppModule) RegisterStoreDecoder

func (am AppModule) RegisterStoreDecoder(_ sdk.StoreDecoderRegistry)

RegisterStoreDecoder registers a decoder

func (AppModule) WeightedOperations

func (am AppModule) WeightedOperations(simState module.SimulationState) []simtypes.WeightedOperation

WeightedOperations returns the all the gov module operations with their respective weights.

type AppModuleBasic

type AppModuleBasic struct {
	// contains filtered or unexported fields
}

AppModuleBasic implements the AppModuleBasic interface for the capability module.

func NewAppModuleBasic

func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic

func (AppModuleBasic) DefaultGenesis

func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage

DefaultGenesis returns the capability module's default genesis state.

func (AppModuleBasic) GetQueryCmd

func (AppModuleBasic) GetQueryCmd() *cobra.Command

GetQueryCmd returns the capability module's root query command.

func (AppModuleBasic) GetTxCmd

func (a AppModuleBasic) GetTxCmd() *cobra.Command

GetTxCmd returns the capability module's root tx command.

func (AppModuleBasic) Name

func (AppModuleBasic) Name() string

Name returns the capability module's name.

func (AppModuleBasic) RegisterCodec

func (AppModuleBasic) RegisterCodec(cdc *codec.LegacyAmino)

func (AppModuleBasic) RegisterGRPCGatewayRoutes

func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux)

RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module.

func (AppModuleBasic) RegisterInterfaces

func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry)

RegisterInterfaces registers the module's interface types

func (AppModuleBasic) RegisterLegacyAminoCodec

func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)

func (AppModuleBasic) RegisterRESTRoutes

func (AppModuleBasic) RegisterRESTRoutes(clientCtx client.Context, rtr *mux.Router)

RegisterRESTRoutes registers the capability module's REST service handlers.

func (AppModuleBasic) ValidateGenesis

func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error

ValidateGenesis performs genesis state validation for the capability module.

Directories

Path Synopsis
client
cli
Package types is a reverse proxy.
Package types is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL