0g-chain/migrate/v0_15/incentive_test.go
Ruaridh a52f606447
Incentive migration state fixes: delegator (#1004)
* add missing delegator claims

* fix tests
2021-08-20 04:13:59 +01:00

605 lines
15 KiB
Go

package v0_15
import (
"testing"
sdk "github.com/cosmos/cosmos-sdk/types"
v0_15staking "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/stretchr/testify/require"
v0_15cdp "github.com/kava-labs/kava/x/cdp/types"
v0_15hard "github.com/kava-labs/kava/x/hard/types"
"github.com/kava-labs/kava/x/incentive"
v0_14incentive "github.com/kava-labs/kava/x/incentive/legacy/v0_14"
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 TestMigrateDelegatorRewardIndexes(t *testing.T) {
type expect struct {
err bool
indexes v0_15incentive.MultiRewardIndexes
}
testCases := []struct {
name string
oldRIs v0_14incentive.RewardIndexes
expected expect
}{
{
name: "single index is migrated correctly",
oldRIs: v0_14incentive.RewardIndexes{{
CollateralType: "ukava",
RewardFactor: sdk.MustNewDecFromStr("0.1"),
}},
expected: expect{
indexes: v0_15incentive.MultiRewardIndexes{{
CollateralType: "ukava",
RewardIndexes: v0_15incentive.RewardIndexes{{
CollateralType: "hard",
RewardFactor: sdk.MustNewDecFromStr("0.1"),
}},
}},
},
},
{
name: "empty index is migrated correctly",
oldRIs: v0_14incentive.RewardIndexes{},
expected: expect{
indexes: v0_15incentive.MultiRewardIndexes{{
CollateralType: "ukava",
RewardIndexes: v0_15incentive.RewardIndexes{},
}},
},
},
{
name: "too many indexes errors",
oldRIs: v0_14incentive.RewardIndexes{
{
CollateralType: "ukava",
RewardFactor: sdk.MustNewDecFromStr("0.1"),
},
{
CollateralType: "btcb",
RewardFactor: sdk.MustNewDecFromStr("0.2"),
},
},
expected: expect{
err: true,
},
},
{
name: "incorrect rewarded denom errors",
oldRIs: v0_14incentive.RewardIndexes{{
CollateralType: "btcb",
RewardFactor: sdk.MustNewDecFromStr("0.1"),
}},
expected: expect{
err: true,
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
actualIndexes, err := migrateDelegatorRewardIndexes(tc.oldRIs)
if tc.expected.err {
require.Error(t, err)
} else {
require.Equal(t, tc.expected.indexes, actualIndexes)
}
})
}
}
func TestAddMissingHardClaims_Basic(t *testing.T) {
claims := v0_15incentive.HardLiquidityProviderClaims{
v0_15incentive.NewHardLiquidityProviderClaim(
sdk.AccAddress("address1"),
sdk.NewCoins(sdk.NewInt64Coin("hard", 1e9)),
v0_15incentive.MultiRewardIndexes{},
v0_15incentive.MultiRewardIndexes{},
),
}
deposits := v0_15hard.Deposits{
v0_15hard.NewDeposit(
sdk.AccAddress("address1"),
nil,
nil,
),
v0_15hard.NewDeposit(
sdk.AccAddress("address2"),
nil,
nil,
),
}
borrows := v0_15hard.Borrows{
v0_15hard.NewBorrow(
sdk.AccAddress("address1"),
nil, // only need the owner address for this test
nil,
),
v0_15hard.NewBorrow(
sdk.AccAddress("address3"),
nil, // only need the owner address for this test
nil,
),
}
actualClaims := addMissingHardClaims(claims, deposits, borrows, nil, nil)
expectedClaims := v0_15incentive.HardLiquidityProviderClaims{
v0_15incentive.NewHardLiquidityProviderClaim(
sdk.AccAddress("address1"),
sdk.NewCoins(sdk.NewInt64Coin("hard", 1e9)),
v0_15incentive.MultiRewardIndexes{},
v0_15incentive.MultiRewardIndexes{},
),
v0_15incentive.NewHardLiquidityProviderClaim(
sdk.AccAddress("address3"),
sdk.NewCoins(),
v0_15incentive.MultiRewardIndexes{},
v0_15incentive.MultiRewardIndexes{},
),
v0_15incentive.NewHardLiquidityProviderClaim(
sdk.AccAddress("address2"),
sdk.NewCoins(),
v0_15incentive.MultiRewardIndexes{},
v0_15incentive.MultiRewardIndexes{},
),
}
require.Equal(t, expectedClaims, actualClaims)
}
func TestAlignClaimIndexes_Basic(t *testing.T) {
claims := v0_15incentive.HardLiquidityProviderClaims{
v0_15incentive.NewHardLiquidityProviderClaim(
sdk.AccAddress("address1"),
sdk.NewCoins(sdk.NewInt64Coin("hard", 1e9)),
v0_15incentive.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: nil,
},
{
CollateralType: "hard",
RewardIndexes: nil,
},
},
v0_15incentive.MultiRewardIndexes{
{
CollateralType: "busd",
RewardIndexes: nil,
},
{
CollateralType: "xrpb",
RewardIndexes: nil,
},
},
),
}
deposits := v0_15hard.Deposits{
v0_15hard.NewDeposit(
sdk.AccAddress("address1"),
sdk.NewCoins(sdk.NewInt64Coin("ukava", 1)),
nil,
),
v0_15hard.NewDeposit(
sdk.AccAddress("address2"),
nil,
nil,
),
}
borrows := v0_15hard.Borrows{
v0_15hard.NewBorrow(
sdk.AccAddress("address1"),
sdk.NewCoins(sdk.NewInt64Coin("xrpb", 1)),
nil,
),
v0_15hard.NewBorrow(
sdk.AccAddress("address3"),
nil,
nil,
),
}
actualClaims := alignClaimIndexes(claims, deposits, borrows, nil, nil)
expectedClaims := v0_15incentive.HardLiquidityProviderClaims{
v0_15incentive.NewHardLiquidityProviderClaim(
sdk.AccAddress("address1"),
sdk.NewCoins(sdk.NewInt64Coin("hard", 1e9)),
v0_15incentive.MultiRewardIndexes{{
CollateralType: "ukava",
RewardIndexes: nil,
}},
v0_15incentive.MultiRewardIndexes{{
CollateralType: "xrpb",
RewardIndexes: nil,
}},
),
}
require.Equal(t, expectedClaims, actualClaims)
}
func TestAlignIndexes(t *testing.T) {
globalRI := v0_15incentive.RewardIndexes{{
CollateralType: "hard",
RewardFactor: sdk.OneDec(),
}}
globalIndexes := v0_15incentive.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: globalRI,
},
{
CollateralType: "hard",
RewardIndexes: globalRI,
},
}
testCases := []struct {
name string
indexes v0_15incentive.MultiRewardIndexes
coins sdk.Coins
expected v0_15incentive.MultiRewardIndexes
}{
{
name: "indexes matching coins are unchanged",
indexes: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: nil,
},
{
CollateralType: "hard", // not in alphabetic order
RewardIndexes: nil,
},
},
coins: sdk.NewCoins(sdk.NewInt64Coin("hard", 1), sdk.NewInt64Coin("ukava", 1)),
expected: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: nil,
},
{
CollateralType: "hard", // order is preserved
RewardIndexes: nil,
},
},
},
{
name: "missing indexes are added from global values",
indexes: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: nil,
},
},
coins: sdk.NewCoins(sdk.NewInt64Coin("hard", 1), sdk.NewInt64Coin("ukava", 1)),
expected: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: nil,
},
{
CollateralType: "hard",
RewardIndexes: globalRI,
},
},
},
{
name: "extra indexes are removed",
indexes: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: nil,
},
{
CollateralType: "hard",
RewardIndexes: nil,
},
},
coins: sdk.NewCoins(sdk.NewInt64Coin("hard", 1)),
expected: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "hard",
RewardIndexes: nil,
},
},
},
{
name: "missing indexes are added even when not in global values",
indexes: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "hard",
RewardIndexes: nil,
},
},
coins: sdk.NewCoins(sdk.NewInt64Coin("hard", 1), sdk.NewInt64Coin("btcb", 1)),
expected: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "hard",
RewardIndexes: nil,
},
{
CollateralType: "btcb",
RewardIndexes: v0_15incentive.RewardIndexes{},
},
},
},
{
name: "empty coins results in empty indexes",
indexes: v0_15incentive.MultiRewardIndexes{
{
CollateralType: "ukava",
RewardIndexes: nil,
},
{
CollateralType: "hard",
RewardIndexes: nil,
},
},
coins: sdk.NewCoins(),
expected: v0_15incentive.MultiRewardIndexes{},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
require.Equal(t, tc.expected, alignIndexes(tc.indexes, tc.coins, globalIndexes))
})
}
}
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)
}
func TestAddMissingDelegatorClaims(t *testing.T) {
claims := v0_15incentive.DelegatorClaims{
v0_15incentive.NewDelegatorClaim(
sdk.AccAddress("address1"),
nil,
nil,
),
v0_15incentive.NewDelegatorClaim(
sdk.AccAddress("address3"),
nil,
nil,
),
}
delegations := v0_15staking.Delegations{
{
DelegatorAddress: sdk.AccAddress("address2"),
},
{
DelegatorAddress: sdk.AccAddress("address1"),
},
{
DelegatorAddress: sdk.AccAddress("address3"),
},
{
DelegatorAddress: sdk.AccAddress("address3"), // there can be multiple delegations per delegator
},
{
DelegatorAddress: sdk.AccAddress("address4"),
},
{
DelegatorAddress: sdk.AccAddress("address4"),
},
}
globalIndexes := v0_15incentive.MultiRewardIndexes{{
CollateralType: "ukava",
RewardIndexes: v0_15incentive.RewardIndexes{
{
CollateralType: "hard",
RewardFactor: sdk.MustNewDecFromStr("0.1"),
},
{
CollateralType: "swp",
RewardFactor: sdk.MustNewDecFromStr("0.2"),
},
},
}}
expectedClaims := v0_15incentive.DelegatorClaims{
v0_15incentive.NewDelegatorClaim(
sdk.AccAddress("address1"),
nil,
nil,
),
v0_15incentive.NewDelegatorClaim(
sdk.AccAddress("address3"),
nil,
nil,
),
v0_15incentive.NewDelegatorClaim(
sdk.AccAddress("address2"),
sdk.NewCoins(),
globalIndexes,
),
v0_15incentive.NewDelegatorClaim(
sdk.AccAddress("address4"),
sdk.NewCoins(),
globalIndexes,
),
}
newClaims := addMissingDelegatorClaims(claims, delegations, globalIndexes)
require.Equal(t, expectedClaims, newClaims)
}