mirror of
https://github.com/0glabs/0g-chain.git
synced 2025-01-12 08:15:18 +00:00
feat: add swap incentives (#1006)
* feat: add swap incentives * add tests that verify swp annual rewards * remove unused testdata file * add test for swp delegator rewards
This commit is contained in:
parent
22843cd3df
commit
3d65ba7caa
@ -2,6 +2,7 @@ package v0_15
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/cosmos/cosmos-sdk/codec"
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
@ -60,8 +61,15 @@ func Incentive(cdc *codec.Codec, incentiveGS v0_14incentive.GenesisState, cdps v
|
|||||||
delegatorRewardPeriods = append(delegatorRewardPeriods, delegatorRewardPeriod)
|
delegatorRewardPeriods = append(delegatorRewardPeriods, delegatorRewardPeriod)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: finalize swap reward pool IDs, rewards per second, start/end times. Should swap rewards start active?
|
swapRewardPeriods := v0_15incentive.MultiRewardPeriods{
|
||||||
swapRewardPeriods := v0_15incentive.MultiRewardPeriods{}
|
v0_15incentive.NewMultiRewardPeriod(true, "bnb:usdx", GenesisTime, GenesisTime.Add(time.Hour*24*365*4), sdk.NewCoins(sdk.NewCoin("swp", sdk.NewInt(47565)))),
|
||||||
|
v0_15incentive.NewMultiRewardPeriod(true, "btcb:usdx", GenesisTime, GenesisTime.Add(time.Hour*24*365*4), sdk.NewCoins(sdk.NewCoin("swp", sdk.NewInt(47565)))),
|
||||||
|
v0_15incentive.NewMultiRewardPeriod(true, "busd:usdx", GenesisTime, GenesisTime.Add(time.Hour*24*365*4), sdk.NewCoins(sdk.NewCoin("swp", sdk.NewInt(158549)))),
|
||||||
|
v0_15incentive.NewMultiRewardPeriod(true, "hard:usdx", GenesisTime, GenesisTime.Add(time.Hour*24*365*4), sdk.NewCoins(sdk.NewCoin("swp", sdk.NewInt(47565)))),
|
||||||
|
v0_15incentive.NewMultiRewardPeriod(true, "swp:usdx", GenesisTime, GenesisTime.Add(time.Hour*24*365*4), sdk.NewCoins(sdk.NewCoin("swp", sdk.NewInt(190259)))),
|
||||||
|
v0_15incentive.NewMultiRewardPeriod(true, "ukava:usdx", GenesisTime, GenesisTime.Add(time.Hour*24*365*4), sdk.NewCoins(sdk.NewCoin("swp", sdk.NewInt(221969)))),
|
||||||
|
v0_15incentive.NewMultiRewardPeriod(true, "usdx:xrpb", GenesisTime, GenesisTime.Add(time.Hour*24*365*4), sdk.NewCoins(sdk.NewCoin("swp", sdk.NewInt(47565)))),
|
||||||
|
}
|
||||||
|
|
||||||
// Build new params from migrated values
|
// Build new params from migrated values
|
||||||
params := v0_15incentive.NewParams(
|
params := v0_15incentive.NewParams(
|
||||||
|
@ -25,12 +25,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
GenesisTime = time.Date(2021, 8, 30, 15, 0, 0, 0, time.UTC) // 1630335600
|
// TODO: update GenesisTime and chain-id for kava-8 launch
|
||||||
ChainID = "kava-8"
|
GenesisTime = time.Date(2021, 8, 30, 15, 0, 0, 0, time.UTC)
|
||||||
// TODO: update SWP reward per second amount before production
|
ChainID = "kava-8"
|
||||||
// TODO: update SWP reward per second amount before production
|
SwpDelegatorRewardsPerSecond = sdk.NewCoin("swp", sdk.NewInt(198186))
|
||||||
SwpDelegatorRewardsPerSecond = sdk.NewCoin("swp", sdk.OneInt())
|
|
||||||
SwpLiquidityProviderRewardsPerSecond = sdk.NewCoin("swp", sdk.OneInt())
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Migrate translates a genesis file from kava v0.14 format to kava v0.15 format
|
// Migrate translates a genesis file from kava v0.14 format to kava v0.15 format
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/kava-labs/kava/x/hard"
|
"github.com/kava-labs/kava/x/hard"
|
||||||
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
||||||
v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
|
v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
|
||||||
|
"github.com/kava-labs/kava/x/swap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
@ -204,6 +205,110 @@ func TestIncentive_Full_TotalRewards(t *testing.T) {
|
|||||||
require.Equal(t, oldTotalRewards.Add(additionalRewards...), newTotalRewards)
|
require.Equal(t, oldTotalRewards.Add(additionalRewards...), newTotalRewards)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIncentive_SwpLPRewards(t *testing.T) {
|
||||||
|
expectedAnnualRewards := sdk.NewCoin("swp", sdk.NewInt(24000000e6))
|
||||||
|
expectedAnnualRewardsMap := map[string]sdk.Coin{
|
||||||
|
"ukava:usdx": sdk.NewCoin("swp", sdk.NewInt(7000000e6)),
|
||||||
|
"swp:usdx": sdk.NewCoin("swp", sdk.NewInt(6000000e6)),
|
||||||
|
"busd:usdx": sdk.NewCoin("swp", sdk.NewInt(5000000e6)),
|
||||||
|
"bnb:usdx": sdk.NewCoin("swp", sdk.NewInt(1500000e6)),
|
||||||
|
"btcb:usdx": sdk.NewCoin("swp", sdk.NewInt(1500000e6)),
|
||||||
|
"hard:usdx": sdk.NewCoin("swp", sdk.NewInt(1500000e6)),
|
||||||
|
"usdx:xrpb": sdk.NewCoin("swp", sdk.NewInt(1500000e6)),
|
||||||
|
}
|
||||||
|
|
||||||
|
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-incentive-state.json"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
var oldIncentiveGenState v0_14incentive.GenesisState
|
||||||
|
cdc := app.MakeCodec()
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
cdc.MustUnmarshalJSON(bz, &oldIncentiveGenState)
|
||||||
|
})
|
||||||
|
secondsPerYear := sdk.NewInt(31536000)
|
||||||
|
|
||||||
|
newGenState := v0_15incentive.GenesisState{}
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
newGenState = Incentive(app.MakeCodec(), oldIncentiveGenState, v0_15cdp.CDPs{})
|
||||||
|
})
|
||||||
|
err = newGenState.Validate()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
actualAnnualRewards := sdk.NewCoin("swp", sdk.ZeroInt())
|
||||||
|
|
||||||
|
for _, rp := range newGenState.Params.SwapRewardPeriods {
|
||||||
|
expected, found := expectedAnnualRewardsMap[rp.CollateralType]
|
||||||
|
require.True(t, found)
|
||||||
|
require.True(t, len(rp.RewardsPerSecond) == 1)
|
||||||
|
require.True(t, rp.RewardsPerSecond[0].Denom == "swp")
|
||||||
|
annualRewardsAmount := rp.RewardsPerSecond[0].Amount.ToDec().Mul(secondsPerYear.ToDec()).RoundInt()
|
||||||
|
annualRewardsCoin := sdk.NewCoin("swp", annualRewardsAmount)
|
||||||
|
actualAnnualRewards = actualAnnualRewards.Add(annualRewardsCoin)
|
||||||
|
// allow for +- 0.1% deviation for targeted annual rewards
|
||||||
|
inRange := assertRewardsWithinRange(expected, annualRewardsCoin, sdk.MustNewDecFromStr("0.001"))
|
||||||
|
require.True(t, inRange, fmt.Sprintf("expected annual rewards: %s, actual %s", expected, annualRewardsCoin))
|
||||||
|
}
|
||||||
|
inRange := assertRewardsWithinRange(expectedAnnualRewards, actualAnnualRewards, sdk.MustNewDecFromStr("0.001"))
|
||||||
|
require.True(t, inRange, fmt.Sprintf("expected annual rewards: %s, actual %s", expectedAnnualRewards, actualAnnualRewards))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIncentive_SwpDelegatorRewards(t *testing.T) {
|
||||||
|
expectedAnnualRewards := sdk.NewCoin("swp", sdk.NewInt(6250000e6))
|
||||||
|
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-incentive-state.json"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
var oldIncentiveGenState v0_14incentive.GenesisState
|
||||||
|
cdc := app.MakeCodec()
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
cdc.MustUnmarshalJSON(bz, &oldIncentiveGenState)
|
||||||
|
})
|
||||||
|
secondsPerYear := sdk.NewInt(31536000)
|
||||||
|
|
||||||
|
newGenState := v0_15incentive.GenesisState{}
|
||||||
|
require.NotPanics(t, func() {
|
||||||
|
newGenState = Incentive(app.MakeCodec(), oldIncentiveGenState, v0_15cdp.CDPs{})
|
||||||
|
})
|
||||||
|
|
||||||
|
for _, rp := range newGenState.Params.DelegatorRewardPeriods {
|
||||||
|
swpRewardsPerSecondDelegators := sdk.NewCoin("swp", rp.RewardsPerSecond.AmountOf("swp"))
|
||||||
|
annualRewardsAmount := swpRewardsPerSecondDelegators.Amount.ToDec().Mul(secondsPerYear.ToDec()).RoundInt()
|
||||||
|
annualRewardsCoin := sdk.NewCoin("swp", annualRewardsAmount)
|
||||||
|
inRange := assertRewardsWithinRange(expectedAnnualRewards, annualRewardsCoin, sdk.MustNewDecFromStr("0.001"))
|
||||||
|
require.True(t, inRange, fmt.Sprintf("expected annual rewards: %s, actual %s", expectedAnnualRewards, annualRewardsCoin))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIncentive_SwpPoolsValid(t *testing.T) {
|
||||||
|
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-test-incentive-state.json"))
|
||||||
|
require.NoError(t, err)
|
||||||
|
appState := genutil.AppMap{v0_14incentive.ModuleName: bz, v0_15cdp.ModuleName: app.MakeCodec().MustMarshalJSON(v0_15cdp.DefaultGenesisState())}
|
||||||
|
|
||||||
|
MigrateAppState(appState)
|
||||||
|
cdc := app.MakeCodec()
|
||||||
|
var swapGS swap.GenesisState
|
||||||
|
cdc.MustUnmarshalJSON(appState[swap.ModuleName], &swapGS)
|
||||||
|
var incentiveGS v0_15incentive.GenesisState
|
||||||
|
cdc.MustUnmarshalJSON(appState[v0_15incentive.ModuleName], &incentiveGS)
|
||||||
|
|
||||||
|
for _, rp := range incentiveGS.Params.SwapRewardPeriods {
|
||||||
|
found := false
|
||||||
|
for _, pool := range swapGS.Params.AllowedPools {
|
||||||
|
if pool.Name() == rp.CollateralType {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require.True(t, found, fmt.Sprintf("incentivized pool %s not found in swap genesis state", rp.CollateralType))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertRewardsWithinRange(expected, actual sdk.Coin, tolerance sdk.Dec) bool {
|
||||||
|
upper := expected.Amount.ToDec().Mul(sdk.OneDec().Add(tolerance))
|
||||||
|
lower := expected.Amount.ToDec().Mul(sdk.OneDec().Sub(tolerance))
|
||||||
|
if actual.Amount.ToDec().GTE(lower) && actual.Amount.ToDec().LTE(upper) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func TestSwap(t *testing.T) {
|
func TestSwap(t *testing.T) {
|
||||||
swapGS := Swap()
|
swapGS := Swap()
|
||||||
err := swapGS.Validate()
|
err := swapGS.Validate()
|
||||||
|
Loading…
Reference in New Issue
Block a user