mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-27 00:35:18 +00:00
add incentive spec
This commit is contained in:
parent
a295b793a9
commit
c1e9a87fb3
5
x/incentive/spec/01_concepts.md
Normal file
5
x/incentive/spec/01_concepts.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Concepts
|
||||||
|
|
||||||
|
This module presents an implementation of user incentives that are controlled by governance. When users take a certain action, in this case opening a CDP, they become eligible for rewards. Rewards are __opt in__ meaning that users must submit a message before the claim deadline to claim their rewards. The goals and background of this module were subject of a previous Kava governance proposal, which can be found [here](https://ipfs.io/ipfs/QmSYedssC3nyQacDJmNcREtgmTPyaMx2JX7RNkMdAVkdkr/user-growth-fund-proposal.pdf).
|
||||||
|
|
||||||
|
When governance adds a collateral type to be eligible for rewards, they set the rate (coins/time) at which rewards are given to users, the length of each reward period, the length of each claim period, and the amount of time reward coins must vest before users who claim them can transfer them. For the duration of a reward period, any user that has minted USDX using an eligible collateral type will ratably accumulate rewards in a `Claim` object. For example, if a user has minted 10% of all USDX for the duration of the reward period, they will earn 10% of all rewards for that period. When the reward period ends, the claim period begins immediately, at which point users can submit a message to claim their rewards. Rewards are time-locked, meaning that when a user claims rewards they will receive them as a vesting balance on their account. Vesting balances can be used to stake coins, but cannot be transferred until the vesting period ends.
|
57
x/incentive/spec/02_state.md
Normal file
57
x/incentive/spec/02_state.md
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
# State
|
||||||
|
|
||||||
|
## Parameters and Genesis State
|
||||||
|
|
||||||
|
`Parameters` define the collateral types which are eligible for rewards, the rate at which rewards are given to users, and the amount of time rewards must vest before users can transfer them.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Params governance parameters for the incentive module
|
||||||
|
type Params struct {
|
||||||
|
Active bool `json:"active" yaml:"active"` // top level governance switch to disable all rewards
|
||||||
|
Rewards Rewards `json:"rewards" yaml:"rewards"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reward stores the specified state for a single reward period.
|
||||||
|
type Reward struct {
|
||||||
|
Active bool `json:"active" yaml:"active"` // governance switch to disable a period
|
||||||
|
Denom string `json:"denom" yaml:"denom"` // the collateral denom rewards apply to, must be found in the cdp collaterals
|
||||||
|
AvailableRewards sdk.Coin `json:"available_rewards" yaml:"available_rewards"` // the total amount of coins distributed per period
|
||||||
|
Duration time.Duration `json:"duration" yaml:"duration"` // the duration of the period
|
||||||
|
TimeLock time.Duration `json:"time_lock" yaml:"time_lock"` // how long rewards for this period are timelocked
|
||||||
|
ClaimDuration time.Duration `json:"claim_duration" yaml:"claim_duration"` // how long users have after the period ends to claim their rewards
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`GenesisState` defines the state that must be persisted when the blockchain stops/restarts in order for normal function of the incentive module to resume.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// GenesisState is the state that must be provided at genesis.
|
||||||
|
type GenesisState struct {
|
||||||
|
Params Params `json:"params" yaml:"params"`
|
||||||
|
PreviousBlockTime time.Time `json:"previous_block_time" yaml:"previous_block_time"`
|
||||||
|
RewardPeriods RewardPeriods `json:"reward_periods" yaml:"reward_periods"`
|
||||||
|
ClaimPeriods ClaimPeriods `json:"claim_periods" yaml:"claim_periods"`
|
||||||
|
Claims Claims `json:"claims" yaml:"claims"`
|
||||||
|
NextClaimPeriodIDs GenesisClaimPeriodIDs `json:"next_claim_period_ids" yaml:"next_claim_period_ids"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Store
|
||||||
|
|
||||||
|
For complete details for how items are stored, see [keys.go](../types/keys.go).
|
||||||
|
|
||||||
|
### Reward Period Creation
|
||||||
|
|
||||||
|
At genesis, or when a collateral is added to rewards, a `RewardPeriod` is created in the store by adding to the existing array of `[]RewardPeriod`. If the previous period for that collateral expired, it is deleted. This implies that, for each collateral, there will only ever be one reward period.
|
||||||
|
|
||||||
|
### Reward Period Deletion
|
||||||
|
|
||||||
|
When a `RewardPeriod` expires, a new `ClaimPeriod` is created in the store with the next sequential ID for that collateral (ie, if the previous claim period was ID 1, the next one will be ID 2) and the current `RewardPeriod` is deleted from the array of `[]RewardPeriod`.
|
||||||
|
|
||||||
|
### Reward Claim Creation
|
||||||
|
|
||||||
|
Every block, CDPs are iterated over and the collateral denom is checked for rewards eligibility. For eligible CDPs, a `RewardClaim` is created in the store for all CDP owners, if one doesn't already exist. The reward object is associated with a `ClaimPeriod` via the ID. This implies that `RewardClaim` are created before `ClaimPeriod` are created. Therefore, a user who submits a `MsgClaimReward` will only be paid out IF 1) they have one or more active `RewardClaim` objects, and 2) if the `ClaimPeriod` with the associated ID for that object exists AND the current block time is between the start time and end time for that `ClaimPeriod`.
|
||||||
|
|
||||||
|
### Reward Claim Deletion
|
||||||
|
|
||||||
|
For claimed rewards, the `RewardClaim` is deleted from the store by deleting the key associated with that denom, ID, and owner. Unclaimed rewards are handled as follows: Each block, the `ClaimPeriod` objects for each denom are iterated over and checked for expiry. If expired, all `RewardClaim` objects for that ID are deleted, as well as the `ClaimPeriod` object. Since claim periods are monotonically increasing, once a non-expired claim period is reached, the iteration can be stopped.
|
16
x/incentive/spec/03_messages.md
Normal file
16
x/incentive/spec/03_messages.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# Messages
|
||||||
|
|
||||||
|
Users claim rewards using a `MsgClaimReward`.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// MsgClaimReward message type used to claim rewards
|
||||||
|
type MsgClaimReward struct {
|
||||||
|
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||||
|
Denom string `json:"denom" yaml:"denom"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## State Modifications
|
||||||
|
|
||||||
|
* Accumulated rewards for active claims are transferred from the `kavadist` module account to the users account as vesting coins
|
||||||
|
* The corresponding claim object(s) are deleted from the store
|
20
x/incentive/spec/04_events.md
Normal file
20
x/incentive/spec/04_events.md
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Events
|
||||||
|
|
||||||
|
The `x/incentive` module emits the following events:
|
||||||
|
|
||||||
|
## MsgClaimReward
|
||||||
|
|
||||||
|
| Type | Attribute Key | Attribute Value |
|
||||||
|
|----------------------|---------------------|--------------------|
|
||||||
|
| claim_reward | claimed_by | {claiming address} |
|
||||||
|
| claim_reward | claim_amount | {amount claimed} |
|
||||||
|
| message | module | incentive |
|
||||||
|
| message | sender | {sender address} |
|
||||||
|
|
||||||
|
## BeginBlock
|
||||||
|
|
||||||
|
| Type | Attribute Key | Attribute Value |
|
||||||
|
|----------------------|---------------------|--------------------|
|
||||||
|
| new_claim_period | claim_period | {claim period} |
|
||||||
|
| new_reward_period | reward_period | {reward period} |
|
||||||
|
| claim_period_expiry | claim_period | {claim period} |
|
19
x/incentive/spec/05_params.md
Normal file
19
x/incentive/spec/05_params.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Parameters
|
||||||
|
|
||||||
|
The incentive module contains the following parameters:
|
||||||
|
|
||||||
|
| Key | Type | Example | Description |
|
||||||
|
|------------|----------------|---------------|--------------------------------------------------|
|
||||||
|
| Active | bool | "true" | boolean for if this module is active |
|
||||||
|
| Rewards | array (Reward) | [{see below}] | array of params for each inflationary period |
|
||||||
|
|
||||||
|
Each `Reward` has the following parameters
|
||||||
|
|
||||||
|
| Key | Type | Example | Description |
|
||||||
|
|------------------|--------------------|----------------------------------|----------------------------------------------------------------|
|
||||||
|
| Active | bool | "true | boolean for if rewards for this collateral are active |
|
||||||
|
| Denom | string | "bnb" | the collateral for which rewards are eligible |
|
||||||
|
| AvailableRewards | object (coin) | {"denom":"kava","amount":"1000"} | the rewards available per reward period |
|
||||||
|
| Duration | string (time ns) | "172800000000000" | the duration of each reward period |
|
||||||
|
| TimeLock | string (time ns) | "172800000000000" | the duration for which claimed rewards will be vesting |
|
||||||
|
| ClaimDuration | string (time ns) | "172800000000000" | how long users have to claim rewards before they expire |
|
11
x/incentive/spec/06_begin_block.md
Normal file
11
x/incentive/spec/06_begin_block.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Begin Block
|
||||||
|
|
||||||
|
At the start of each block, expired claims and claim periods are deleted, rewards are applied to CDPs for any ongoing reward periods, expired reward periods are deleted and replaced with a new reward period (if active), and claim periods are created for expiring reward periods. The logic is as follows:
|
||||||
|
|
||||||
|
```go
|
||||||
|
func BeginBlocker(ctx sdk.Context, k Keeper) {
|
||||||
|
k.DeleteExpiredClaimsAndClaimPeriods(ctx)
|
||||||
|
k.ApplyRewardsToCdps(ctx)
|
||||||
|
k.CreateAndDeleteRewardPeriods(ctx)
|
||||||
|
}
|
||||||
|
```
|
17
x/incentive/spec/README.md
Normal file
17
x/incentive/spec/README.md
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# `incentive`
|
||||||
|
|
||||||
|
<!-- TOC -->
|
||||||
|
1. **[Concepts](01_concepts.md)**
|
||||||
|
2. **[State](02_state.md)**
|
||||||
|
3. **[Messages](03_messages.md)**
|
||||||
|
4. **[Events](04_events.md)**
|
||||||
|
5. **[Params](05_params.md)**
|
||||||
|
6. **[BeginBlock](06_begin_block.md)**
|
||||||
|
|
||||||
|
## Abstract
|
||||||
|
|
||||||
|
`x/incentive` is an implementation of a Cosmos SDK Module that allows for governance controlled user incentives for users who create stable assets by opening a collateralized debt position (CDP). Governance proposes an array of collateral rewards, with each item representing a collateral type that will be eligible for rewards. Each collateral reward specifies the number of coins awarded per period, the length of rewards periods, the length of claim periods. Governance can alter the collateral rewards using parameter change proposals as well as adding or removing collateral types. All changes to parameters would take place in the _next_ period.
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
This module depends on `x/cdp` for users to be able to create CDPs and on `x/kavadist`, which controls the module account from where rewards are spent. In the event that the module account is not funded, user's attempt to claim rewards will fail.
|
Loading…
Reference in New Issue
Block a user