mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +00:00
Incentive migration state fixes: USDX Minting (#998)
* minor migration refactor * overwrite usdx claims with latest reward indexes * add missing usdx claims in migration * add script to calculate missing usdx rewards * generate missing rewards using preliminary data * add missing usdx rewards in migration * update missing rewards data to use correct genesis * test rewards were not decreased * add tests for missing reward calculations * clarify function names * test to assert total new rewards are as expected * remove unecessary todo item
This commit is contained in:
parent
cac7398120
commit
22843cd3df
9
migrate/v0_15/generate-test-incentive-data.sh
Executable file
9
migrate/v0_15/generate-test-incentive-data.sh
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "Usage: ./generate-test-incentive-data.sh genesis.json"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
jq < "$1" -c '{"incentive": .app_state.incentive, "cdp": .app_state.cdp }' > testdata/kava-7-test-incentive-state.json
|
@ -1,14 +1,18 @@
|
|||||||
package v0_15
|
package v0_15
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
|
v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
|
||||||
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"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Incentive migrates from a v0.14 incentive genesis state to a v0.15 incentive genesis state
|
// Incentive migrates from a v0.14 incentive genesis state to a v0.15 incentive genesis state
|
||||||
func Incentive(incentiveGS v0_14incentive.GenesisState) v0_15incentive.GenesisState {
|
func Incentive(cdc *codec.Codec, incentiveGS v0_14incentive.GenesisState, cdps v0_15cdp.CDPs) v0_15incentive.GenesisState {
|
||||||
// Migrate params
|
// Migrate params
|
||||||
claimMultipliers := v0_15incentive.Multipliers{}
|
claimMultipliers := v0_15incentive.Multipliers{}
|
||||||
for _, m := range incentiveGS.Params.ClaimMultipliers {
|
for _, m := range incentiveGS.Params.ClaimMultipliers {
|
||||||
@ -78,12 +82,13 @@ func Incentive(incentiveGS v0_14incentive.GenesisState) v0_15incentive.GenesisSt
|
|||||||
swapGenesisRewardState := v0_15incentive.DefaultGenesisRewardState // There is no previous swap rewards so accumulation starts at genesis time.
|
swapGenesisRewardState := v0_15incentive.DefaultGenesisRewardState // There is no previous swap rewards so accumulation starts at genesis time.
|
||||||
|
|
||||||
// Migrate USDX minting claims
|
// Migrate USDX minting claims
|
||||||
usdxMintingClaims := v0_15incentive.USDXMintingClaims{}
|
usdxMintingClaims := migrateUSDXMintingClaims(incentiveGS.USDXMintingClaims)
|
||||||
for _, claim := range incentiveGS.USDXMintingClaims {
|
usdxMintingFormattedIndexes := convertRewardIndexesToUSDXMintingIndexes(usdxGenesisRewardState.MultiRewardIndexes)
|
||||||
rewardIndexes := migrateRewardIndexes(claim.RewardIndexes)
|
usdxMintingClaims = replaceUSDXClaimIndexes(usdxMintingClaims, usdxMintingFormattedIndexes)
|
||||||
usdxMintingClaim := v0_15incentive.NewUSDXMintingClaim(claim.Owner, claim.Reward, rewardIndexes)
|
usdxMintingClaims = ensureAllCDPsHaveClaims(usdxMintingClaims, cdps, usdxMintingFormattedIndexes)
|
||||||
usdxMintingClaims = append(usdxMintingClaims, usdxMintingClaim)
|
var missedRewards map[string]sdk.Coin
|
||||||
}
|
cdc.MustUnmarshalJSON([]byte(missedUSDXMintingRewards), &missedRewards)
|
||||||
|
usdxMintingClaims = addRewards(usdxMintingClaims, missedRewards)
|
||||||
|
|
||||||
// Migrate Hard protocol claims (includes creating new Delegator claims)
|
// Migrate Hard protocol claims (includes creating new Delegator claims)
|
||||||
hardClaims := v0_15incentive.HardLiquidityProviderClaims{}
|
hardClaims := v0_15incentive.HardLiquidityProviderClaims{}
|
||||||
@ -135,6 +140,83 @@ func Incentive(incentiveGS v0_14incentive.GenesisState) v0_15incentive.GenesisSt
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// migrateUSDXMintingClaims converts the a slice of v0.14 USDX minting claims into v0.15 USDX minting claims.
|
||||||
|
// As both types are the same underneath, this just converts types and does no other modification.
|
||||||
|
func migrateUSDXMintingClaims(oldClaims v0_14incentive.USDXMintingClaims) v0_15incentive.USDXMintingClaims {
|
||||||
|
newClaims := v0_15incentive.USDXMintingClaims{}
|
||||||
|
for _, oldClaim := range oldClaims {
|
||||||
|
rewardIndexes := migrateRewardIndexes(oldClaim.RewardIndexes)
|
||||||
|
usdxMintingClaim := v0_15incentive.NewUSDXMintingClaim(oldClaim.Owner, oldClaim.Reward, rewardIndexes)
|
||||||
|
newClaims = append(newClaims, usdxMintingClaim)
|
||||||
|
}
|
||||||
|
return newClaims
|
||||||
|
}
|
||||||
|
|
||||||
|
// replaceUSDXClaimIndexes overwrites the reward indexes in all the claims with the current global indexes.
|
||||||
|
func replaceUSDXClaimIndexes(claims v0_15incentive.USDXMintingClaims, globalIndexes v0_15incentive.RewardIndexes) v0_15incentive.USDXMintingClaims {
|
||||||
|
var amendedClaims v0_15incentive.USDXMintingClaims
|
||||||
|
for _, claim := range claims {
|
||||||
|
claim.RewardIndexes = globalIndexes
|
||||||
|
amendedClaims = append(amendedClaims, claim)
|
||||||
|
}
|
||||||
|
return amendedClaims
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertRewardIndexesToUSDXMintingIndexes converts a genesis reward indexes into the format used within usdx minting claims.
|
||||||
|
func convertRewardIndexesToUSDXMintingIndexes(mris v0_15incentive.MultiRewardIndexes) v0_15incentive.RewardIndexes {
|
||||||
|
var newIndexes v0_15incentive.RewardIndexes
|
||||||
|
for _, mri := range mris {
|
||||||
|
factor, found := mri.RewardIndexes.Get(v0_15incentive.USDXMintingRewardDenom)
|
||||||
|
if !found {
|
||||||
|
panic(fmt.Sprintf("found global usdx minting reward index without denom '%s': %s", v0_15incentive.USDXMintingRewardDenom, mri))
|
||||||
|
}
|
||||||
|
newIndexes = newIndexes.With(mri.CollateralType, factor)
|
||||||
|
}
|
||||||
|
return newIndexes
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensureAllCDPsHaveClaims ensures that there is a claim for every cdp in the provided list.
|
||||||
|
// It uses the provided global indexes as the indexes for any added claim.
|
||||||
|
func ensureAllCDPsHaveClaims(newClaims v0_15incentive.USDXMintingClaims, cdps v0_15cdp.CDPs, globalIndexes v0_15incentive.RewardIndexes) v0_15incentive.USDXMintingClaims {
|
||||||
|
for _, cdp := range cdps {
|
||||||
|
|
||||||
|
claimFound := false
|
||||||
|
for _, claim := range newClaims {
|
||||||
|
if claim.Owner.Equals(cdp.Owner) {
|
||||||
|
claimFound = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !claimFound {
|
||||||
|
|
||||||
|
claim := v0_15incentive.NewUSDXMintingClaim(
|
||||||
|
cdp.Owner,
|
||||||
|
sdk.NewCoin(v0_15incentive.USDXMintingRewardDenom, sdk.ZeroInt()),
|
||||||
|
globalIndexes,
|
||||||
|
)
|
||||||
|
newClaims = append(newClaims, claim)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return newClaims
|
||||||
|
}
|
||||||
|
|
||||||
|
// addRewards adds some coins to a list of claims according to a map of address: coin.
|
||||||
|
// It panics if any coin denom doesn't match the denom in the claim.
|
||||||
|
func addRewards(newClaims v0_15incentive.USDXMintingClaims, rewards map[string]sdk.Coin) v0_15incentive.USDXMintingClaims {
|
||||||
|
|
||||||
|
var amendedClaims v0_15incentive.USDXMintingClaims
|
||||||
|
for _, claim := range newClaims {
|
||||||
|
r, found := rewards[claim.Owner.String()]
|
||||||
|
if found {
|
||||||
|
claim.Reward = claim.Reward.Add(r)
|
||||||
|
}
|
||||||
|
amendedClaims = append(amendedClaims, claim)
|
||||||
|
}
|
||||||
|
return amendedClaims
|
||||||
|
}
|
||||||
|
|
||||||
func migrateMultiRewardPeriods(oldPeriods v0_14incentive.MultiRewardPeriods) v0_15incentive.MultiRewardPeriods {
|
func migrateMultiRewardPeriods(oldPeriods v0_14incentive.MultiRewardPeriods) v0_15incentive.MultiRewardPeriods {
|
||||||
newPeriods := v0_15incentive.MultiRewardPeriods{}
|
newPeriods := v0_15incentive.MultiRewardPeriods{}
|
||||||
for _, rp := range oldPeriods {
|
for _, rp := range oldPeriods {
|
||||||
|
184
migrate/v0_15/incentive_test.go
Normal file
184
migrate/v0_15/incentive_test.go
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
package v0_15
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
|
||||||
|
"github.com/kava-labs/kava/x/incentive"
|
||||||
|
v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// d parses a string into an sdk.Dec type.
|
||||||
|
// It is an alias for sdk.MustNewDecFromStr.
|
||||||
|
var d = sdk.MustNewDecFromStr
|
||||||
|
|
||||||
|
func TestReplaceUSDXClaimIndexes(t *testing.T) {
|
||||||
|
claims := incentive.USDXMintingClaims{
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address1"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 1e9),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0.1")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address2"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0")},
|
||||||
|
{CollateralType: "xrpb-a", RewardFactor: d("0.2")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address3"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
globalIndexes := incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0.5")},
|
||||||
|
{CollateralType: "xrpb-a", RewardFactor: d("0.8")},
|
||||||
|
}
|
||||||
|
|
||||||
|
syncedClaims := replaceUSDXClaimIndexes(claims, globalIndexes)
|
||||||
|
|
||||||
|
for i, claim := range syncedClaims {
|
||||||
|
// check fields are unchanged
|
||||||
|
require.Equal(t, claim.Owner, claims[i].Owner)
|
||||||
|
require.Equal(t, claim.Reward, claims[i].Reward)
|
||||||
|
// except for indexes which have been overwritten
|
||||||
|
require.Equal(t, globalIndexes, claim.RewardIndexes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEnsureAllCDPsHaveClaims(t *testing.T) {
|
||||||
|
claims := incentive.USDXMintingClaims{
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address1"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 1e9),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0.1")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address2"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0")},
|
||||||
|
{CollateralType: "xrpb-a", RewardFactor: d("0.2")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address3"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
cdps := v0_15cdp.CDPs{
|
||||||
|
{Owner: sdk.AccAddress("address4")}, // don't need anything more than owner for this test
|
||||||
|
{Owner: sdk.AccAddress("address1")}, // there can be several cdps of different types with same owner
|
||||||
|
{Owner: sdk.AccAddress("address1")},
|
||||||
|
{Owner: sdk.AccAddress("address1")},
|
||||||
|
{Owner: sdk.AccAddress("address2")},
|
||||||
|
}
|
||||||
|
|
||||||
|
globalIndexes := incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0.5")},
|
||||||
|
{CollateralType: "xrpb-a", RewardFactor: d("0.8")},
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedClaims := incentive.USDXMintingClaims{
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address1"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 1e9),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0.1")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address2"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0")},
|
||||||
|
{CollateralType: "xrpb-a", RewardFactor: d("0.2")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address3"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address4"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0.5")},
|
||||||
|
{CollateralType: "xrpb-a", RewardFactor: d("0.8")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, expectedClaims, ensureAllCDPsHaveClaims(claims, cdps, globalIndexes))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddRewards(t *testing.T) {
|
||||||
|
claims := v0_15incentive.USDXMintingClaims{
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address1"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 1e9),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0.1")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address2"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0")},
|
||||||
|
{CollateralType: "xrpb-a", RewardFactor: d("0.2")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address3"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
rewards := map[string]sdk.Coin{
|
||||||
|
sdk.AccAddress("address1").String(): sdk.NewInt64Coin(v0_15incentive.USDXMintingRewardDenom, 1e9),
|
||||||
|
sdk.AccAddress("address3").String(): sdk.NewInt64Coin(v0_15incentive.USDXMintingRewardDenom, 3e9),
|
||||||
|
sdk.AccAddress("address4").String(): sdk.NewInt64Coin(v0_15incentive.USDXMintingRewardDenom, 1e6),
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedClaims := v0_15incentive.USDXMintingClaims{
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address1"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 2e9),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0.1")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address2"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 0),
|
||||||
|
incentive.RewardIndexes{
|
||||||
|
{CollateralType: "bnb-a", RewardFactor: d("0")},
|
||||||
|
{CollateralType: "xrpb-a", RewardFactor: d("0.2")},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address3"),
|
||||||
|
sdk.NewInt64Coin(incentive.USDXMintingRewardDenom, 3e9),
|
||||||
|
incentive.RewardIndexes{},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
amendedClaims := addRewards(claims, rewards)
|
||||||
|
require.Equal(t, expectedClaims, amendedClaims)
|
||||||
|
}
|
@ -14,6 +14,7 @@ import (
|
|||||||
tmtypes "github.com/tendermint/tendermint/types"
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
|
v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
|
||||||
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
||||||
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
||||||
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
|
||||||
@ -78,7 +79,12 @@ func MigrateAppState(v0_14AppState genutil.AppMap) {
|
|||||||
var incentiveGenState v0_14incentive.GenesisState
|
var incentiveGenState v0_14incentive.GenesisState
|
||||||
v0_14Codec.MustUnmarshalJSON(v0_14AppState[v0_14incentive.ModuleName], &incentiveGenState)
|
v0_14Codec.MustUnmarshalJSON(v0_14AppState[v0_14incentive.ModuleName], &incentiveGenState)
|
||||||
delete(v0_14AppState, v0_14incentive.ModuleName)
|
delete(v0_14AppState, v0_14incentive.ModuleName)
|
||||||
v0_14AppState[v0_15incentive.ModuleName] = v0_15Codec.MustMarshalJSON(Incentive(incentiveGenState))
|
|
||||||
|
// unmarshal all cdps using v0_15 types as there has been no changes since v0_14
|
||||||
|
var cdpGenState v0_15cdp.GenesisState
|
||||||
|
v0_15Codec.MustUnmarshalJSON(v0_14AppState[v0_15cdp.ModuleName], &cdpGenState)
|
||||||
|
|
||||||
|
v0_14AppState[v0_15incentive.ModuleName] = v0_15Codec.MustMarshalJSON(Incentive(v0_15Codec, incentiveGenState, cdpGenState.CDPs))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Migrate commmittee app state
|
// Migrate commmittee app state
|
||||||
|
@ -13,11 +13,12 @@ import (
|
|||||||
"github.com/cosmos/cosmos-sdk/x/auth"
|
"github.com/cosmos/cosmos-sdk/x/auth"
|
||||||
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
|
||||||
"github.com/cosmos/cosmos-sdk/x/genutil"
|
"github.com/cosmos/cosmos-sdk/x/genutil"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
tmtypes "github.com/tendermint/tendermint/types"
|
||||||
|
|
||||||
"github.com/kava-labs/kava/app"
|
"github.com/kava-labs/kava/app"
|
||||||
|
v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
|
||||||
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
v0_14committee "github.com/kava-labs/kava/x/committee/legacy/v0_14"
|
||||||
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
v0_15committee "github.com/kava-labs/kava/x/committee/types"
|
||||||
"github.com/kava-labs/kava/x/hard"
|
"github.com/kava-labs/kava/x/hard"
|
||||||
@ -63,40 +64,144 @@ func TestCommittee(t *testing.T) {
|
|||||||
require.Equal(t, len(oldSPCP.AllowedMarkets), len(newSPCP.AllowedMarkets))
|
require.Equal(t, len(oldSPCP.AllowedMarkets), len(newSPCP.AllowedMarkets))
|
||||||
require.Equal(t, len(oldSPCP.AllowedMoneyMarkets), len(newSPCP.AllowedMoneyMarkets))
|
require.Equal(t, len(oldSPCP.AllowedMoneyMarkets), len(newSPCP.AllowedMoneyMarkets))
|
||||||
}
|
}
|
||||||
func TestIncentive_MainnetState(t *testing.T) {
|
|
||||||
// TODO add copy of mainnet state to json
|
func TestIncentive_Full(t *testing.T) {
|
||||||
bz, err := ioutil.ReadFile(filepath.Join("testdata", "kava-7-incentive-state.json"))
|
t.Skip() // skip to avoid having to commit a large genesis file to the repo
|
||||||
|
|
||||||
|
genDoc, err := tmtypes.GenesisDocFromFile(filepath.Join("testdata", "genesis.json"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
cdc := makeV014Codec()
|
||||||
|
|
||||||
|
var oldState genutil.AppMap
|
||||||
|
cdc.MustUnmarshalJSON(genDoc.AppState, &oldState)
|
||||||
|
|
||||||
var oldIncentiveGenState v0_14incentive.GenesisState
|
var oldIncentiveGenState v0_14incentive.GenesisState
|
||||||
cdc := app.MakeCodec()
|
cdc.MustUnmarshalJSON(oldState[v0_14incentive.ModuleName], &oldIncentiveGenState)
|
||||||
require.NotPanics(t, func() {
|
|
||||||
cdc.MustUnmarshalJSON(bz, &oldIncentiveGenState)
|
|
||||||
})
|
|
||||||
|
|
||||||
newGenState := v0_15incentive.GenesisState{}
|
var oldCDPGenState v0_15cdp.GenesisState
|
||||||
require.NotPanics(t, func() {
|
cdc.MustUnmarshalJSON(oldState[v0_15cdp.ModuleName], &oldCDPGenState)
|
||||||
newGenState = Incentive(oldIncentiveGenState)
|
|
||||||
})
|
newGenState := Incentive(app.MakeCodec(), oldIncentiveGenState, oldCDPGenState.CDPs)
|
||||||
err = newGenState.Validate()
|
require.NoError(t, newGenState.Validate())
|
||||||
require.NoError(t, err)
|
|
||||||
|
// TODO check params, indexes, and accumulation times
|
||||||
|
|
||||||
|
// Ensure the usdx claim indexes match global
|
||||||
|
globalIndexes := newGenState.USDXRewardState.MultiRewardIndexes
|
||||||
|
for _, claim := range newGenState.USDXMintingClaims {
|
||||||
|
|
||||||
|
for _, globalIndex := range globalIndexes {
|
||||||
|
expectedFactor, found := globalIndex.RewardIndexes.Get(v0_15incentive.USDXMintingRewardDenom)
|
||||||
|
require.True(t, found)
|
||||||
|
|
||||||
|
factor, found := claim.RewardIndexes.Get(globalIndex.CollateralType)
|
||||||
|
require.True(t, found)
|
||||||
|
|
||||||
|
require.Equal(t, expectedFactor, factor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure there is a usdx claim for every cdp
|
||||||
|
for _, cdp := range oldCDPGenState.CDPs {
|
||||||
|
numClaims := 0
|
||||||
|
for _, claim := range newGenState.USDXMintingClaims {
|
||||||
|
if cdp.Owner.Equals(claim.Owner) {
|
||||||
|
numClaims++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
require.Equal(t, 1, numClaims, "cdp '%s' has invalid number of claims '%d'", cdp.Owner, numClaims)
|
||||||
|
|
||||||
|
// also check cdp indexes are valid
|
||||||
|
require.True(t, cdp.InterestFactor.GTE(sdk.OneDec()), "found cdp with interest factor < 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check reward amounts
|
||||||
|
for _, claim := range newGenState.USDXMintingClaims {
|
||||||
|
|
||||||
|
// check a few high value accounts
|
||||||
|
switch claim.Owner.String() {
|
||||||
|
// check reward is: additional reward + existing unclaimed reward
|
||||||
|
// note, non zero unclaimed rewards could change if the user submits a claim tx before launch
|
||||||
|
case "kava1k8lymw58tduy9gm6jkt04ddkjd83nf7sm8xthl":
|
||||||
|
require.Equal(t, sdk.NewInt(370982556999+0), claim.Reward.Amount)
|
||||||
|
case "kava1p3ucd3ptpw902fluyjzhq3ffgq4ntddaysyq8h":
|
||||||
|
require.Equal(t, sdk.NewInt(77550672285+16960713469), claim.Reward.Amount)
|
||||||
|
case "kava1qe6ahdnhnfugle29054d8uqg7fa44ryx934yc6":
|
||||||
|
require.Equal(t, sdk.NewInt(40874651319+0), claim.Reward.Amount)
|
||||||
|
case "kava12h6pq2xqzgtxttrzg7q2rplsyxtv2dc5gwh8rl":
|
||||||
|
require.Equal(t, sdk.NewInt(30867752254+0), claim.Reward.Amount)
|
||||||
|
case "kava10hczxv0p3eadcwgt5u79yhahsyuw98u26qan50":
|
||||||
|
require.Equal(t, sdk.NewInt(22429344254+0), claim.Reward.Amount)
|
||||||
|
case "kava15wyjwhj6zh79m7adm69pwl3nsq9z8gs9ezs4k7":
|
||||||
|
require.Equal(t, sdk.NewInt(10252596901+0), claim.Reward.Amount)
|
||||||
|
case "kava1yg4840l77dfs5zqflldhut27en2mhvvc8vj93x":
|
||||||
|
require.Equal(t, sdk.NewInt(9898765520+0), claim.Reward.Amount)
|
||||||
|
case "kava1x242qk6jf2rv23ruvk6fmxp97gg2y75a9r2caq":
|
||||||
|
require.Equal(t, sdk.NewInt(7761701231+0), claim.Reward.Amount)
|
||||||
|
case "kava1tstf3u4cw7u4xyu7wxdrnmrpvvmfamq3twcj7f":
|
||||||
|
require.Equal(t, sdk.NewInt(2466900572+0), claim.Reward.Amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
// check no rewards have been reduced
|
||||||
|
for _, oldClaim := range oldIncentiveGenState.USDXMintingClaims {
|
||||||
|
if oldClaim.Owner.Equals(claim.Owner) {
|
||||||
|
require.Truef(t, claim.Reward.IsGTE(oldClaim.Reward), "found claim with reduced rewards, old %s, new %s", oldClaim, claim)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
require.Equal(t, len(oldIncentiveGenState.USDXMintingClaims), len(newGenState.USDXMintingClaims))
|
|
||||||
require.Equal(t, len(oldIncentiveGenState.HardLiquidityProviderClaims), len(newGenState.HardLiquidityProviderClaims))
|
require.Equal(t, len(oldIncentiveGenState.HardLiquidityProviderClaims), len(newGenState.HardLiquidityProviderClaims))
|
||||||
// 1 new DelegatorClaim should have been created for each existing HardLiquidityProviderClaim
|
// 1 new DelegatorClaim should have been created for each existing HardLiquidityProviderClaim
|
||||||
require.Equal(t, len(oldIncentiveGenState.HardLiquidityProviderClaims), len(newGenState.DelegatorClaims))
|
require.Equal(t, len(oldIncentiveGenState.HardLiquidityProviderClaims), len(newGenState.DelegatorClaims))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIncentive(t *testing.T) {
|
func TestIncentive_Full_TotalRewards(t *testing.T) {
|
||||||
bz, err := ioutil.ReadFile(filepath.Join("testdata", "v0_14-incentive-state.json"))
|
t.Skip() // skip to avoid having to commit a large genesis file to the repo
|
||||||
require.NoError(t, err)
|
|
||||||
appState := genutil.AppMap{v0_14incentive.ModuleName: bz}
|
|
||||||
|
|
||||||
MigrateAppState(appState)
|
genDoc, err := tmtypes.GenesisDocFromFile(filepath.Join("testdata", "genesis.json"))
|
||||||
|
|
||||||
bz, err = ioutil.ReadFile(filepath.Join("testdata", "v0_15-incentive-state.json"))
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.JSONEq(t, string(bz), string(appState[v0_15incentive.ModuleName]))
|
cdc := makeV014Codec()
|
||||||
|
|
||||||
|
var oldState genutil.AppMap
|
||||||
|
cdc.MustUnmarshalJSON(genDoc.AppState, &oldState)
|
||||||
|
|
||||||
|
var oldIncentiveGenState v0_14incentive.GenesisState
|
||||||
|
cdc.MustUnmarshalJSON(oldState[v0_14incentive.ModuleName], &oldIncentiveGenState)
|
||||||
|
|
||||||
|
var oldCDPGenState v0_15cdp.GenesisState
|
||||||
|
cdc.MustUnmarshalJSON(oldState[v0_15cdp.ModuleName], &oldCDPGenState)
|
||||||
|
|
||||||
|
newGenState := Incentive(app.MakeCodec(), oldIncentiveGenState, oldCDPGenState.CDPs)
|
||||||
|
|
||||||
|
// total previous rewards
|
||||||
|
oldTotalRewards := sdk.NewCoins() // total synced unclaimed rewards
|
||||||
|
for _, claim := range oldIncentiveGenState.HardLiquidityProviderClaims {
|
||||||
|
oldTotalRewards = oldTotalRewards.Add(claim.Reward...)
|
||||||
|
}
|
||||||
|
for _, claim := range oldIncentiveGenState.USDXMintingClaims {
|
||||||
|
oldTotalRewards = oldTotalRewards.Add(claim.Reward)
|
||||||
|
}
|
||||||
|
|
||||||
|
// total new rewards
|
||||||
|
newTotalRewards := sdk.NewCoins() // total synced unclaimed rewards
|
||||||
|
for _, claim := range newGenState.USDXMintingClaims {
|
||||||
|
newTotalRewards = newTotalRewards.Add(claim.Reward)
|
||||||
|
}
|
||||||
|
for _, claim := range newGenState.HardLiquidityProviderClaims {
|
||||||
|
newTotalRewards = newTotalRewards.Add(claim.Reward...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rewards added in migration
|
||||||
|
additionalRewards := sdk.NewCoins()
|
||||||
|
var missedRewards map[string]sdk.Coin
|
||||||
|
cdc.MustUnmarshalJSON([]byte(missedUSDXMintingRewards), &missedRewards)
|
||||||
|
for _, c := range missedRewards {
|
||||||
|
additionalRewards = additionalRewards.Add(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
require.Equal(t, oldTotalRewards.Add(additionalRewards...), newTotalRewards)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSwap(t *testing.T) {
|
func TestSwap(t *testing.T) {
|
||||||
|
5
migrate/v0_15/rewards.go
Normal file
5
migrate/v0_15/rewards.go
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
277
migrate/v0_15/testdata/v0_14-incentive-state.json
vendored
277
migrate/v0_15/testdata/v0_14-incentive-state.json
vendored
@ -1,277 +0,0 @@
|
|||||||
{
|
|
||||||
"hard_borrow_accumulation_times": [],
|
|
||||||
"hard_borrow_reward_indexes": [],
|
|
||||||
"hard_delegator_accumulation_times": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hard_delegator_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hard_liquidity_provider_claims": [
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zx2gfs37vszrgrxke22mtlfj6hpl72y03ur7xr",
|
|
||||||
"reward": [
|
|
||||||
{
|
|
||||||
"amount": "48396109",
|
|
||||||
"denom": "hard"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amount": "1",
|
|
||||||
"denom": "ukava"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"borrow_reward_indexes": [],
|
|
||||||
"delegator_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"supply_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "usdx",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zyu77sruwsk7vw8pkcrj20ees0gyjlfntrgahy",
|
|
||||||
"reward": []
|
|
||||||
},
|
|
||||||
"borrow_reward_indexes": [],
|
|
||||||
"delegator_reward_indexes": [],
|
|
||||||
"supply_reward_indexes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zyu7gxmdcd7x83ndl2nvegj57lasf7cel4nrex",
|
|
||||||
"reward": [
|
|
||||||
{
|
|
||||||
"amount": "6442528",
|
|
||||||
"denom": "hard"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"borrow_reward_indexes": [],
|
|
||||||
"delegator_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"supply_reward_indexes": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hard_supply_accumulation_times": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "usdx",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hard_supply_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "usdx",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"params": {
|
|
||||||
"claim_end": "2026-04-08T14:00:00Z",
|
|
||||||
"claim_multipliers": [
|
|
||||||
{
|
|
||||||
"factor": "0.200000000000000000",
|
|
||||||
"months_lockup": "1",
|
|
||||||
"name": "small"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"factor": "1.000000000000000000",
|
|
||||||
"months_lockup": "12",
|
|
||||||
"name": "large"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hard_borrow_reward_periods": [],
|
|
||||||
"hard_delegator_reward_periods": [
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"end": "2024-10-16T14:00:00Z",
|
|
||||||
"rewards_per_second": {
|
|
||||||
"amount": "633761",
|
|
||||||
"denom": "hard"
|
|
||||||
},
|
|
||||||
"start": "2020-10-16T14:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hard_supply_reward_periods": [
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "usdx",
|
|
||||||
"end": "2024-10-16T14:00:00Z",
|
|
||||||
"rewards_per_second": [
|
|
||||||
{
|
|
||||||
"amount": "373919",
|
|
||||||
"denom": "hard"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amount": "373919",
|
|
||||||
"denom": "ukava"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": "2020-10-16T14:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "bnb",
|
|
||||||
"end": "2024-10-16T14:00:00Z",
|
|
||||||
"rewards_per_second": [
|
|
||||||
{
|
|
||||||
"amount": "12675",
|
|
||||||
"denom": "hard"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": "2020-10-16T14:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"usdx_minting_reward_periods": [
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "btcb-a",
|
|
||||||
"end": "2022-04-08T14:00:00Z",
|
|
||||||
"rewards_per_second": {
|
|
||||||
"amount": "110780",
|
|
||||||
"denom": "ukava"
|
|
||||||
},
|
|
||||||
"start": "2021-04-08T15:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"end": "2022-04-08T14:00:00Z",
|
|
||||||
"rewards_per_second": {
|
|
||||||
"amount": "122354",
|
|
||||||
"denom": "ukava"
|
|
||||||
},
|
|
||||||
"start": "2021-04-08T15:00:00Z"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"usdx_accumulation_times": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "btcb-a",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"usdx_minting_claims": [
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava177dtrf8ahjp3wud6p3aqurpuyqae3mq8n069m9",
|
|
||||||
"reward": {
|
|
||||||
"amount": "81528",
|
|
||||||
"denom": "ukava"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava18dde5uvs9h474wj5pe69wg66s2v30whpsqgwee",
|
|
||||||
"reward": {
|
|
||||||
"amount": "4825232",
|
|
||||||
"denom": "ukava"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "btcb-a",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"usdx_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "btcb-a",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
367
migrate/v0_15/testdata/v0_15-incentive-state.json
vendored
367
migrate/v0_15/testdata/v0_15-incentive-state.json
vendored
@ -1,367 +0,0 @@
|
|||||||
{
|
|
||||||
"delegator_claims": [
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zx2gfs37vszrgrxke22mtlfj6hpl72y03ur7xr",
|
|
||||||
"reward": []
|
|
||||||
},
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zyu77sruwsk7vw8pkcrj20ees0gyjlfntrgahy",
|
|
||||||
"reward": []
|
|
||||||
},
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_indexes": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zyu7gxmdcd7x83ndl2nvegj57lasf7cel4nrex",
|
|
||||||
"reward": []
|
|
||||||
},
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"delegator_reward_state": {
|
|
||||||
"accumulation_times": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"multi_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"hard_borrow_reward_state": {
|
|
||||||
"accumulation_times": [],
|
|
||||||
"multi_reward_indexes": []
|
|
||||||
},
|
|
||||||
"hard_liquidity_provider_claims": [
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zx2gfs37vszrgrxke22mtlfj6hpl72y03ur7xr",
|
|
||||||
"reward": [
|
|
||||||
{
|
|
||||||
"amount": "48396109",
|
|
||||||
"denom": "hard"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amount": "1",
|
|
||||||
"denom": "ukava"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"borrow_reward_indexes": [],
|
|
||||||
"supply_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "usdx",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zyu77sruwsk7vw8pkcrj20ees0gyjlfntrgahy",
|
|
||||||
"reward": []
|
|
||||||
},
|
|
||||||
"borrow_reward_indexes": [],
|
|
||||||
"supply_reward_indexes": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava1zyu7gxmdcd7x83ndl2nvegj57lasf7cel4nrex",
|
|
||||||
"reward": [
|
|
||||||
{
|
|
||||||
"amount": "6442528",
|
|
||||||
"denom": "hard"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"borrow_reward_indexes": [],
|
|
||||||
"supply_reward_indexes": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hard_supply_reward_state": {
|
|
||||||
"accumulation_times": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "usdx",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"multi_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "usdx",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "hard",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"params": {
|
|
||||||
"claim_end": "2026-04-08T14:00:00Z",
|
|
||||||
"claim_multipliers": [
|
|
||||||
{
|
|
||||||
"denom": "hard",
|
|
||||||
"multipliers": [
|
|
||||||
{
|
|
||||||
"name": "small",
|
|
||||||
"months_lockup": "1",
|
|
||||||
"factor": "0.200000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "large",
|
|
||||||
"months_lockup": "12",
|
|
||||||
"factor": "1.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"denom": "ukava",
|
|
||||||
"multipliers": [
|
|
||||||
{
|
|
||||||
"name": "small",
|
|
||||||
"months_lockup": "1",
|
|
||||||
"factor": "0.200000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "large",
|
|
||||||
"months_lockup": "12",
|
|
||||||
"factor": "1.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"denom": "swp",
|
|
||||||
"multipliers": [
|
|
||||||
{
|
|
||||||
"name": "small",
|
|
||||||
"months_lockup": "1",
|
|
||||||
"factor": "0.100000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "large",
|
|
||||||
"months_lockup": "12",
|
|
||||||
"factor": "1.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"delegator_reward_periods": [
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"end": "2024-10-16T14:00:00Z",
|
|
||||||
"rewards_per_second": [
|
|
||||||
{
|
|
||||||
"amount": "633761",
|
|
||||||
"denom": "hard"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amount": "1",
|
|
||||||
"denom": "swp"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": "2020-10-16T14:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"hard_borrow_reward_periods": [],
|
|
||||||
"hard_supply_reward_periods": [
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "usdx",
|
|
||||||
"end": "2024-10-16T14:00:00Z",
|
|
||||||
"rewards_per_second": [
|
|
||||||
{
|
|
||||||
"amount": "373919",
|
|
||||||
"denom": "hard"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"amount": "373919",
|
|
||||||
"denom": "ukava"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": "2020-10-16T14:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "bnb",
|
|
||||||
"end": "2024-10-16T14:00:00Z",
|
|
||||||
"rewards_per_second": [
|
|
||||||
{
|
|
||||||
"amount": "12675",
|
|
||||||
"denom": "hard"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start": "2020-10-16T14:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"swap_reward_periods": [],
|
|
||||||
"usdx_minting_reward_periods": [
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "btcb-a",
|
|
||||||
"end": "2022-04-08T14:00:00Z",
|
|
||||||
"rewards_per_second": {
|
|
||||||
"amount": "110780",
|
|
||||||
"denom": "ukava"
|
|
||||||
},
|
|
||||||
"start": "2021-04-08T15:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"active": true,
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"end": "2022-04-08T14:00:00Z",
|
|
||||||
"rewards_per_second": {
|
|
||||||
"amount": "122354",
|
|
||||||
"denom": "ukava"
|
|
||||||
},
|
|
||||||
"start": "2021-04-08T15:00:00Z"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"swap_claims": [],
|
|
||||||
"swap_reward_state": {
|
|
||||||
"accumulation_times": [],
|
|
||||||
"multi_reward_indexes": []
|
|
||||||
},
|
|
||||||
"usdx_minting_claims": [
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava177dtrf8ahjp3wud6p3aqurpuyqae3mq8n069m9",
|
|
||||||
"reward": {
|
|
||||||
"amount": "81528",
|
|
||||||
"denom": "ukava"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"base_claim": {
|
|
||||||
"owner": "kava18dde5uvs9h474wj5pe69wg66s2v30whpsqgwee",
|
|
||||||
"reward": {
|
|
||||||
"amount": "4825232",
|
|
||||||
"denom": "ukava"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "btcb-a",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"usdx_reward_state": {
|
|
||||||
"accumulation_times": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "btcb-a",
|
|
||||||
"previous_accumulation_time": "2021-04-08T15:00:00Z"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"multi_reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "bnb-a",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"collateral_type": "btcb-a",
|
|
||||||
"reward_indexes": [
|
|
||||||
{
|
|
||||||
"collateral_type": "ukava",
|
|
||||||
"reward_factor": "0.000000000000000000"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
108
migrate/v0_15/usdx_rewards/calculate.go
Normal file
108
migrate/v0_15/usdx_rewards/calculate.go
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
|
|
||||||
|
v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
|
||||||
|
v0_15incentive "github.com/kava-labs/kava/x/incentive"
|
||||||
|
)
|
||||||
|
|
||||||
|
type rewards map[string]sdk.Coin
|
||||||
|
|
||||||
|
type rewardsCalculator struct {
|
||||||
|
claims v0_15incentive.USDXMintingClaims
|
||||||
|
globalIndexes v0_15incentive.RewardIndexes
|
||||||
|
cdps v0_15cdp.CDPs
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRewardsCalculator(claims v0_15incentive.USDXMintingClaims, globalIndexes v0_15incentive.RewardIndexes, cdps v0_15cdp.CDPs) rewardsCalculator {
|
||||||
|
return rewardsCalculator{
|
||||||
|
claims: claims,
|
||||||
|
globalIndexes: globalIndexes,
|
||||||
|
cdps: cdps,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate synchronizes all of the claims and returns the new rewards to be added by owner address.
|
||||||
|
func (rc rewardsCalculator) Calculate() (rewards, error) {
|
||||||
|
rewards := rewards{}
|
||||||
|
|
||||||
|
for _, claim := range rc.claims {
|
||||||
|
|
||||||
|
reward, err := rc.calculateRewardsForClaim(claim)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, found := rewards[claim.Owner.String()]; found {
|
||||||
|
return nil, fmt.Errorf("duplicate claim found: %s", claim.Owner)
|
||||||
|
}
|
||||||
|
if !reward.IsZero() {
|
||||||
|
rewards[claim.Owner.String()] = reward
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rewards, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculateRewardsForClaim synchronizes the claim to and returns the new rewards that should be added.
|
||||||
|
// It syncs against the stored global indexes, looking up cdps for the source share amounts.
|
||||||
|
func (rc rewardsCalculator) calculateRewardsForClaim(claim v0_15incentive.USDXMintingClaim) (sdk.Coin, error) {
|
||||||
|
reward := sdk.ZeroInt()
|
||||||
|
|
||||||
|
for _, index := range rc.globalIndexes {
|
||||||
|
oldFactor, found := claim.RewardIndexes.Get(index.CollateralType)
|
||||||
|
if !found {
|
||||||
|
oldFactor = sdk.ZeroDec()
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceShares := sdk.ZeroDec()
|
||||||
|
cdp, found := rc.getCDP(claim.Owner, index.CollateralType)
|
||||||
|
if found {
|
||||||
|
sourceShares = cdp.GetTotalPrincipal().Amount.ToDec()
|
||||||
|
}
|
||||||
|
|
||||||
|
amount, err := rc.calculateSingleReward(oldFactor, index.RewardFactor, sourceShares)
|
||||||
|
if err != nil {
|
||||||
|
return sdk.Coin{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
reward = reward.Add(amount)
|
||||||
|
}
|
||||||
|
return sdk.NewCoin(v0_15incentive.USDXMintingRewardDenom, reward), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculateSingleReward computes how much rewards should have accrued to a reward source (eg a user's btcb-a cdp principal)
|
||||||
|
// between two index values.
|
||||||
|
func (rc rewardsCalculator) calculateSingleReward(oldIndex, newIndex, sourceShares sdk.Dec) (sdk.Int, error) {
|
||||||
|
increase := newIndex.Sub(oldIndex)
|
||||||
|
if increase.IsNegative() {
|
||||||
|
return sdk.Int{}, sdkerrors.Wrapf(v0_15incentive.ErrDecreasingRewardFactor, "old: %v, new: %v", oldIndex, newIndex)
|
||||||
|
}
|
||||||
|
reward := increase.Mul(sourceShares).RoundInt()
|
||||||
|
return reward, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getCDP looks up a cdp by owner and collateral type.
|
||||||
|
func (rc rewardsCalculator) getCDP(owner sdk.AccAddress, collateralType string) (v0_15cdp.CDP, bool) {
|
||||||
|
for _, cdp := range rc.cdps {
|
||||||
|
if cdp.Owner.Equals(owner) && cdp.Type == collateralType {
|
||||||
|
return cdp, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v0_15cdp.CDP{}, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertRewardIndexesToUSDXMintingIndexes(mris v0_15incentive.MultiRewardIndexes) v0_15incentive.RewardIndexes {
|
||||||
|
var newIndexes v0_15incentive.RewardIndexes
|
||||||
|
for _, mri := range mris {
|
||||||
|
factor, found := mri.RewardIndexes.Get(v0_15incentive.USDXMintingRewardDenom)
|
||||||
|
if !found {
|
||||||
|
panic(fmt.Sprintf("found global usdx minting reward index without denom '%s': %s", v0_15incentive.USDXMintingRewardDenom, mri))
|
||||||
|
}
|
||||||
|
newIndexes = newIndexes.With(mri.CollateralType, factor)
|
||||||
|
}
|
||||||
|
return newIndexes
|
||||||
|
}
|
124
migrate/v0_15/usdx_rewards/calculate_test.go
Normal file
124
migrate/v0_15/usdx_rewards/calculate_test.go
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
|
||||||
|
v0_15incentive "github.com/kava-labs/kava/x/incentive/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCalculateRewardsForClaim(t *testing.T) {
|
||||||
|
type expect struct {
|
||||||
|
amount sdk.Int
|
||||||
|
err bool
|
||||||
|
}
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
claimIndexes v0_15incentive.RewardIndexes
|
||||||
|
globalIndexes v0_15incentive.RewardIndexes
|
||||||
|
cdps v0_15cdp.CDPs
|
||||||
|
expected expect
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "single cdp is synced",
|
||||||
|
claimIndexes: v0_15incentive.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "busd-a",
|
||||||
|
RewardFactor: sdk.MustNewDecFromStr("0.1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
globalIndexes: v0_15incentive.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "busd-a",
|
||||||
|
RewardFactor: sdk.MustNewDecFromStr("0.2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cdps: v0_15cdp.CDPs{{
|
||||||
|
Owner: sdk.AccAddress("address1"),
|
||||||
|
Type: "busd-a",
|
||||||
|
Principal: sdk.NewInt64Coin("usdx", 1000),
|
||||||
|
AccumulatedFees: sdk.NewInt64Coin("usdx", 10),
|
||||||
|
}},
|
||||||
|
expected: expect{amount: sdk.NewInt(101)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "missing claim index is assumed 0",
|
||||||
|
claimIndexes: v0_15incentive.RewardIndexes{},
|
||||||
|
globalIndexes: v0_15incentive.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "busd-a",
|
||||||
|
RewardFactor: sdk.MustNewDecFromStr("0.2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cdps: v0_15cdp.CDPs{{
|
||||||
|
Owner: sdk.AccAddress("address1"),
|
||||||
|
Type: "busd-a",
|
||||||
|
Principal: sdk.NewInt64Coin("usdx", 1000),
|
||||||
|
AccumulatedFees: sdk.NewInt64Coin("usdx", 10),
|
||||||
|
}},
|
||||||
|
expected: expect{amount: sdk.NewInt(202)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "multiple cdps are synced",
|
||||||
|
claimIndexes: v0_15incentive.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "busd-a",
|
||||||
|
RewardFactor: sdk.MustNewDecFromStr("0.1"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CollateralType: "xrpb-a",
|
||||||
|
RewardFactor: sdk.MustNewDecFromStr("1"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
globalIndexes: v0_15incentive.RewardIndexes{
|
||||||
|
{
|
||||||
|
CollateralType: "busd-a",
|
||||||
|
RewardFactor: sdk.MustNewDecFromStr("0.2"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
CollateralType: "xrpb-a",
|
||||||
|
RewardFactor: sdk.MustNewDecFromStr("2"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
cdps: v0_15cdp.CDPs{
|
||||||
|
{
|
||||||
|
Owner: sdk.AccAddress("address1"),
|
||||||
|
Type: "busd-a",
|
||||||
|
Principal: sdk.NewInt64Coin("usdx", 1000),
|
||||||
|
AccumulatedFees: sdk.NewInt64Coin("usdx", 100),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Owner: sdk.AccAddress("address1"),
|
||||||
|
Type: "xrpb-a",
|
||||||
|
Principal: sdk.NewInt64Coin("usdx", 10),
|
||||||
|
AccumulatedFees: sdk.NewInt64Coin("usdx", 1),
|
||||||
|
}},
|
||||||
|
expected: expect{amount: sdk.NewInt(110 + 11)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
rc := rewardsCalculator{
|
||||||
|
globalIndexes: tc.globalIndexes,
|
||||||
|
cdps: tc.cdps,
|
||||||
|
}
|
||||||
|
reward, err := rc.calculateRewardsForClaim(v0_15incentive.NewUSDXMintingClaim(
|
||||||
|
sdk.AccAddress("address1"),
|
||||||
|
sdk.NewInt64Coin("ukava", 0),
|
||||||
|
tc.claimIndexes,
|
||||||
|
))
|
||||||
|
|
||||||
|
if tc.expected.err {
|
||||||
|
require.Error(t, err)
|
||||||
|
} else {
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, v0_15incentive.USDXMintingRewardDenom, reward.Denom)
|
||||||
|
require.Truef(t, tc.expected.amount.Equal(reward.Amount), "amount not equal %s, %s", tc.expected.amount, reward.Amount)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
41137
migrate/v0_15/usdx_rewards/cdp-cdps-829296.json
Normal file
41137
migrate/v0_15/usdx_rewards/cdp-cdps-829296.json
Normal file
File diff suppressed because it is too large
Load Diff
43040
migrate/v0_15/usdx_rewards/incentive-usdx-claims-829296.json
Normal file
43040
migrate/v0_15/usdx_rewards/incentive-usdx-claims-829296.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,65 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"collateral_type": "bnb-a",
|
||||||
|
"reward_indexes": [
|
||||||
|
{
|
||||||
|
"collateral_type": "ukava",
|
||||||
|
"reward_factor": "0.043949244534927716"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collateral_type": "btcb-a",
|
||||||
|
"reward_indexes": [
|
||||||
|
{
|
||||||
|
"collateral_type": "ukava",
|
||||||
|
"reward_factor": "0.046551281526135881"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collateral_type": "busd-a",
|
||||||
|
"reward_indexes": [
|
||||||
|
{
|
||||||
|
"collateral_type": "ukava",
|
||||||
|
"reward_factor": "0.011468527653896411"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collateral_type": "hard-a",
|
||||||
|
"reward_indexes": [
|
||||||
|
{
|
||||||
|
"collateral_type": "ukava",
|
||||||
|
"reward_factor": "0.123365881475003544"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collateral_type": "hbtc-a",
|
||||||
|
"reward_indexes": [
|
||||||
|
{
|
||||||
|
"collateral_type": "ukava",
|
||||||
|
"reward_factor": "1.472331865900201761"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collateral_type": "ukava-a",
|
||||||
|
"reward_indexes": [
|
||||||
|
{
|
||||||
|
"collateral_type": "ukava",
|
||||||
|
"reward_factor": "0.038864939729274249"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collateral_type": "xrpb-a",
|
||||||
|
"reward_indexes": [
|
||||||
|
{
|
||||||
|
"collateral_type": "ukava",
|
||||||
|
"reward_factor": "0.020676676769949043"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
87
migrate/v0_15/usdx_rewards/main.go
Normal file
87
migrate/v0_15/usdx_rewards/main.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
// package main calculates missing rewards from kava-7 so they can be include in the migration to kava-8.
|
||||||
|
// In the migration folder run `go run ./usdx_rewards` to compute the output file. The output is a go file so it can be included in the migrations.
|
||||||
|
// Data is taken from an export at height 829296 of kava-7 using v0.14.3.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/codec"
|
||||||
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
|
|
||||||
|
"github.com/kava-labs/kava/app"
|
||||||
|
v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
|
||||||
|
v0_15incentive "github.com/kava-labs/kava/x/incentive"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
outFileName = "rewards.go"
|
||||||
|
|
||||||
|
dirPath = "./usdx_rewards"
|
||||||
|
cdpsFileName = filepath.Join(dirPath, "cdp-cdps-829296.json")
|
||||||
|
indexesFileName = filepath.Join(dirPath, "incentive-usdx-indexes-829296.json")
|
||||||
|
claimsFileName = filepath.Join(dirPath, "incentive-usdx-claims-829296.json")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app.SetBech32AddressPrefixes(sdk.GetConfig())
|
||||||
|
cdc := app.MakeCodec()
|
||||||
|
|
||||||
|
var cdps v0_15cdp.CDPs
|
||||||
|
if err := fetchFromJSONFile(cdc, cdpsFileName, &cdps); err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
var globalIndexes v0_15incentive.MultiRewardIndexes
|
||||||
|
if err := fetchFromJSONFile(cdc, indexesFileName, &globalIndexes); err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
var claims v0_15incentive.USDXMintingClaims
|
||||||
|
if err := fetchFromJSONFile(cdc, claimsFileName, &claims); err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
calculator := NewRewardsCalculator(claims, convertRewardIndexesToUSDXMintingIndexes(globalIndexes), cdps)
|
||||||
|
rewards, err := calculator.Calculate()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
out := createOutputString(cdc, rewards)
|
||||||
|
|
||||||
|
if err = ioutil.WriteFile(outFileName, []byte(out), 0644); err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetchFromJSONFile reads and unmarshals the contents of a json file.
|
||||||
|
func fetchFromJSONFile(cdc *codec.Codec, filePath string, pointer interface{}) error {
|
||||||
|
|
||||||
|
bz, err := ioutil.ReadFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = cdc.UnmarshalJSON(bz, pointer); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func createOutputString(cdc *codec.Codec, rewards rewards) string {
|
||||||
|
bz := cdc.MustMarshalJSON(rewards)
|
||||||
|
|
||||||
|
// sort json keys so make changes easier to compare
|
||||||
|
bz = sdk.MustSortJSON(bz)
|
||||||
|
|
||||||
|
out := `// Code generated by package ./usdx_rewards DO NOT EDIT.
|
||||||
|
|
||||||
|
package v0_15
|
||||||
|
|
||||||
|
var missedUSDXMintingRewards = ` + "`" + string(bz) + "`\n"
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user