mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 04:47:27 +00:00 
			
		
		
		
	Harvest: interest rate model params (#719)
* add interest rate models to params * move interest rate models to money market param * add interest rate models to store * update store interest rate models from params * refactor money market init function, update tests * use cmp package for optimized comparison * implement equal function, remove gocmp dep * delete unseen interest rate model param from store
This commit is contained in:
		
							parent
							
								
									fba4860331
								
							
						
					
					
						commit
						e1ad9569a7
					
				
							
								
								
									
										1
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.sum
									
									
									
									
									
								
							@ -159,7 +159,6 @@ github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ
 | 
			
		||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 | 
			
		||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 | 
			
		||||
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
 | 
			
		||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 | 
			
		||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
 | 
			
		||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
 | 
			
		||||
 | 
			
		||||
@ -11,5 +11,6 @@ func BeginBlocker(ctx sdk.Context, k Keeper) {
 | 
			
		||||
		k.ApplyDelegationRewards(ctx, k.BondDenom(ctx))
 | 
			
		||||
		k.SetPreviousDelegationDistribution(ctx, ctx.BlockTime(), k.BondDenom(ctx))
 | 
			
		||||
	}
 | 
			
		||||
	k.ApplyInterestRateUpdates(ctx)
 | 
			
		||||
	k.SetPreviousBlockTime(ctx, ctx.BlockTime())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -275,12 +275,12 @@ func (suite *KeeperTestSuite) TestBorrow() {
 | 
			
		||||
				),
 | 
			
		||||
				},
 | 
			
		||||
				types.MoneyMarkets{
 | 
			
		||||
					types.NewMoneyMarket("usdx", true, tc.args.usdxBorrowLimit, sdk.MustNewDecFromStr("1"), "usdx:usd", sdk.NewInt(USDX_CF)),
 | 
			
		||||
					types.NewMoneyMarket("busd", false, sdk.NewDec(100000000*BUSD_CF), sdk.MustNewDecFromStr("1"), "busd:usd", sdk.NewInt(BUSD_CF)),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(100000000*KAVA_CF), tc.args.loanToValueKAVA, "kava:usd", sdk.NewInt(KAVA_CF)),
 | 
			
		||||
					types.NewMoneyMarket("btcb", false, sdk.NewDec(100000000*BTCB_CF), tc.args.loanToValueBTCB, "btcb:usd", sdk.NewInt(BTCB_CF)),
 | 
			
		||||
					types.NewMoneyMarket("bnb", false, sdk.NewDec(100000000*BNB_CF), tc.args.loanToValueBNB, "bnb:usd", sdk.NewInt(BNB_CF)),
 | 
			
		||||
					types.NewMoneyMarket("xyz", false, sdk.NewDec(1), tc.args.loanToValueBNB, "xyz:usd", sdk.NewInt(1)),
 | 
			
		||||
					types.NewMoneyMarket("usdx", true, tc.args.usdxBorrowLimit, sdk.MustNewDecFromStr("1"), "usdx:usd", sdk.NewInt(USDX_CF), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("busd", false, sdk.NewDec(100000000*BUSD_CF), sdk.MustNewDecFromStr("1"), "busd:usd", sdk.NewInt(BUSD_CF), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(100000000*KAVA_CF), tc.args.loanToValueKAVA, "kava:usd", sdk.NewInt(KAVA_CF), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("btcb", false, sdk.NewDec(100000000*BTCB_CF), tc.args.loanToValueBTCB, "btcb:usd", sdk.NewInt(BTCB_CF), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("bnb", false, sdk.NewDec(100000000*BNB_CF), tc.args.loanToValueBNB, "bnb:usd", sdk.NewInt(BNB_CF), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("xyz", false, sdk.NewDec(1), tc.args.loanToValueBNB, "xyz:usd", sdk.NewInt(1), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
				},
 | 
			
		||||
			), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -265,8 +265,8 @@ func (suite *KeeperTestSuite) TestClaim() {
 | 
			
		||||
				),
 | 
			
		||||
				},
 | 
			
		||||
				types.MoneyMarkets{
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
				},
 | 
			
		||||
			), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
 | 
			
		||||
			tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
 | 
			
		||||
 | 
			
		||||
@ -108,8 +108,8 @@ func (suite *KeeperTestSuite) TestDeposit() {
 | 
			
		||||
				),
 | 
			
		||||
				},
 | 
			
		||||
				types.MoneyMarkets{
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
				},
 | 
			
		||||
			), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
 | 
			
		||||
			tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
 | 
			
		||||
@ -251,8 +251,8 @@ func (suite *KeeperTestSuite) TestWithdraw() {
 | 
			
		||||
				),
 | 
			
		||||
				},
 | 
			
		||||
				types.MoneyMarkets{
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
				},
 | 
			
		||||
			), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
 | 
			
		||||
			tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								x/harvest/keeper/interest.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								x/harvest/keeper/interest.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
package keeper
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	"github.com/kava-labs/kava/x/harvest/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ApplyInterestRateUpdates translates the current interest rate models from the params to the store
 | 
			
		||||
func (k Keeper) ApplyInterestRateUpdates(ctx sdk.Context) {
 | 
			
		||||
	denomSet := map[string]bool{}
 | 
			
		||||
 | 
			
		||||
	params := k.GetParams(ctx)
 | 
			
		||||
	for _, mm := range params.MoneyMarkets {
 | 
			
		||||
		model, found := k.GetInterestRateModel(ctx, mm.Denom)
 | 
			
		||||
		if !found {
 | 
			
		||||
			k.SetInterestRateModel(ctx, mm.Denom, mm.InterestRateModel)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		if !model.Equal(mm.InterestRateModel) {
 | 
			
		||||
			k.SetInterestRateModel(ctx, mm.Denom, mm.InterestRateModel)
 | 
			
		||||
		}
 | 
			
		||||
		denomSet[mm.Denom] = true
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	k.IterateInterestRateModels(ctx, func(denom string, i types.InterestRateModel) bool {
 | 
			
		||||
		if !denomSet[denom] {
 | 
			
		||||
			k.DeleteInterestRateModel(ctx, denom)
 | 
			
		||||
		}
 | 
			
		||||
		return false
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
@ -255,3 +255,43 @@ func (k Keeper) GetBorrowedCoins(ctx sdk.Context) (sdk.Coins, bool) {
 | 
			
		||||
	k.cdc.MustUnmarshalBinaryBare(bz, &borrowedCoins)
 | 
			
		||||
	return borrowedCoins, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetInterestRateModel returns an interest rate model from the store for a denom
 | 
			
		||||
func (k Keeper) GetInterestRateModel(ctx sdk.Context, denom string) (types.InterestRateModel, bool) {
 | 
			
		||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.InterestRateModelsPrefix)
 | 
			
		||||
	bz := store.Get([]byte(denom))
 | 
			
		||||
	if bz == nil {
 | 
			
		||||
		return types.InterestRateModel{}, false
 | 
			
		||||
	}
 | 
			
		||||
	var interestRateModel types.InterestRateModel
 | 
			
		||||
	k.cdc.MustUnmarshalBinaryBare(bz, &interestRateModel)
 | 
			
		||||
	return interestRateModel, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetInterestRateModel sets an interest rate model in the store for a denom
 | 
			
		||||
func (k Keeper) SetInterestRateModel(ctx sdk.Context, denom string, interestRateModel types.InterestRateModel) {
 | 
			
		||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.InterestRateModelsPrefix)
 | 
			
		||||
	bz := k.cdc.MustMarshalBinaryBare(interestRateModel)
 | 
			
		||||
	store.Set([]byte(denom), bz)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DeleteInterestRateModel deletes an interest rate model from the store
 | 
			
		||||
func (k Keeper) DeleteInterestRateModel(ctx sdk.Context, denom string) {
 | 
			
		||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.InterestRateModelsPrefix)
 | 
			
		||||
	store.Delete([]byte(denom))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IterateInterestRateModels iterates over all interest rate model objects in the store and performs a callback function
 | 
			
		||||
// 		that returns both the interest rate model value and the key it's stored under
 | 
			
		||||
func (k Keeper) IterateInterestRateModels(ctx sdk.Context, cb func(denom string, interestRateModel types.InterestRateModel) (stop bool)) {
 | 
			
		||||
	store := prefix.NewStore(ctx.KVStore(k.key), types.InterestRateModelsPrefix)
 | 
			
		||||
	iterator := sdk.KVStorePrefixIterator(store, []byte{})
 | 
			
		||||
	defer iterator.Close()
 | 
			
		||||
	for ; iterator.Valid(); iterator.Next() {
 | 
			
		||||
		var interestRateModel types.InterestRateModel
 | 
			
		||||
		k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &interestRateModel)
 | 
			
		||||
		if cb(string(iterator.Key()), interestRateModel) {
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
package keeper_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/stretchr/testify/suite"
 | 
			
		||||
@ -153,6 +154,51 @@ func (suite *KeeperTestSuite) TestGetSetDeleteClaim() {
 | 
			
		||||
	suite.Require().False(f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *KeeperTestSuite) TestGetSetDeleteInterestRateModel() {
 | 
			
		||||
	denom := "test"
 | 
			
		||||
	model := types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))
 | 
			
		||||
 | 
			
		||||
	_, f := suite.keeper.GetInterestRateModel(suite.ctx, denom)
 | 
			
		||||
	suite.Require().False(f)
 | 
			
		||||
 | 
			
		||||
	suite.keeper.SetInterestRateModel(suite.ctx, denom, model)
 | 
			
		||||
 | 
			
		||||
	testInterestRateModel, f := suite.keeper.GetInterestRateModel(suite.ctx, denom)
 | 
			
		||||
	suite.Require().True(f)
 | 
			
		||||
	suite.Require().Equal(model, testInterestRateModel)
 | 
			
		||||
 | 
			
		||||
	suite.Require().NotPanics(func() { suite.keeper.DeleteInterestRateModel(suite.ctx, denom) })
 | 
			
		||||
 | 
			
		||||
	_, f = suite.keeper.GetInterestRateModel(suite.ctx, denom)
 | 
			
		||||
	suite.Require().False(f)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *KeeperTestSuite) TestIterateInterestRateModels() {
 | 
			
		||||
	testDenom := "test"
 | 
			
		||||
	var setModels types.InterestRateModels
 | 
			
		||||
	var setDenoms []string
 | 
			
		||||
	for i := 0; i < 5; i++ {
 | 
			
		||||
		denom := testDenom + strconv.Itoa(i)
 | 
			
		||||
		model := types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))
 | 
			
		||||
		suite.Require().NotPanics(func() { suite.keeper.SetInterestRateModel(suite.ctx, denom, model) })
 | 
			
		||||
		// Save the denom and model
 | 
			
		||||
		setDenoms = append(setDenoms, denom)
 | 
			
		||||
		setModels = append(setModels, model)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var seenModels types.InterestRateModels
 | 
			
		||||
	var seenDenoms []string
 | 
			
		||||
	suite.keeper.IterateInterestRateModels(suite.ctx, func(denom string, i types.InterestRateModel) bool {
 | 
			
		||||
		seenDenoms = append(seenDenoms, denom)
 | 
			
		||||
		seenModels = append(seenModels, i)
 | 
			
		||||
		return false
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	suite.Require().Equal(setModels, seenModels)
 | 
			
		||||
	suite.Require().Equal(setDenoms, seenDenoms)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *KeeperTestSuite) getAccount(addr sdk.AccAddress) authexported.Account {
 | 
			
		||||
	ak := suite.app.GetAccountKeeper()
 | 
			
		||||
	return ak.GetAccount(suite.ctx, addr)
 | 
			
		||||
 | 
			
		||||
@ -75,8 +75,8 @@ func (suite *KeeperTestSuite) TestApplyDepositRewards() {
 | 
			
		||||
				),
 | 
			
		||||
				},
 | 
			
		||||
				types.MoneyMarkets{
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
				},
 | 
			
		||||
			), tc.args.previousBlockTime, types.DefaultDistributionTimes)
 | 
			
		||||
			tApp.InitializeFromGenesisStates(app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
 | 
			
		||||
@ -443,8 +443,8 @@ func harvestGenesisState(rewardRate sdk.Coin) app.GenesisState {
 | 
			
		||||
				),
 | 
			
		||||
			},
 | 
			
		||||
			types.MoneyMarkets{
 | 
			
		||||
				types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000)),
 | 
			
		||||
				types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000)),
 | 
			
		||||
				types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
				types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
			},
 | 
			
		||||
		),
 | 
			
		||||
		types.DefaultPreviousBlockTime,
 | 
			
		||||
 | 
			
		||||
@ -291,8 +291,8 @@ func (suite *KeeperTestSuite) TestSendTimeLockedCoinsToAccount() {
 | 
			
		||||
				),
 | 
			
		||||
				},
 | 
			
		||||
				types.MoneyMarkets{
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000)),
 | 
			
		||||
					types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
					types.NewMoneyMarket("ukava", false, sdk.NewDec(1000000000000000), loanToValue, "kava:usd", sdk.NewInt(1000000), types.NewInterestRateModel(sdk.MustNewDecFromStr("0.05"), sdk.MustNewDecFromStr("2"), sdk.MustNewDecFromStr("0.8"), sdk.MustNewDecFromStr("10"))),
 | 
			
		||||
				},
 | 
			
		||||
			), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
 | 
			
		||||
			tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,7 @@ var (
 | 
			
		||||
	ClaimsKeyPrefix                   = []byte{0x04}
 | 
			
		||||
	BorrowsKeyPrefix                  = []byte{0x05}
 | 
			
		||||
	BorrowedCoinsPrefix               = []byte{0x06}
 | 
			
		||||
	InterestRateModelsPrefix          = []byte{0x07}
 | 
			
		||||
	sep                               = []byte(":")
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -253,20 +253,22 @@ func (bl BorrowLimit) Validate() error {
 | 
			
		||||
 | 
			
		||||
// MoneyMarket is a money market for an individual asset
 | 
			
		||||
type MoneyMarket struct {
 | 
			
		||||
	Denom            string      `json:"denom" yaml:"denom"`
 | 
			
		||||
	BorrowLimit      BorrowLimit `json:"borrow_limit" yaml:"borrow_limit"`
 | 
			
		||||
	SpotMarketID     string      `json:"spot_market_id" yaml:"spot_market_id"`
 | 
			
		||||
	ConversionFactor sdk.Int     `json:"conversion_factor" yaml:"conversion_factor"`
 | 
			
		||||
	Denom             string            `json:"denom" yaml:"denom"`
 | 
			
		||||
	BorrowLimit       BorrowLimit       `json:"borrow_limit" yaml:"borrow_limit"`
 | 
			
		||||
	SpotMarketID      string            `json:"spot_market_id" yaml:"spot_market_id"`
 | 
			
		||||
	ConversionFactor  sdk.Int           `json:"conversion_factor" yaml:"conversion_factor"`
 | 
			
		||||
	InterestRateModel InterestRateModel `json:"interest_rate_model" yaml:"interest_rate_model"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewMoneyMarket returns a new MoneyMarket
 | 
			
		||||
func NewMoneyMarket(denom string, hasMaxLimit bool, maximumLimit, loanToValue sdk.Dec,
 | 
			
		||||
	spotMarketID string, conversionFactor sdk.Int) MoneyMarket {
 | 
			
		||||
	spotMarketID string, conversionFactor sdk.Int, interestRateModel InterestRateModel) MoneyMarket {
 | 
			
		||||
	return MoneyMarket{
 | 
			
		||||
		Denom:            denom,
 | 
			
		||||
		BorrowLimit:      NewBorrowLimit(hasMaxLimit, maximumLimit, loanToValue),
 | 
			
		||||
		SpotMarketID:     spotMarketID,
 | 
			
		||||
		ConversionFactor: conversionFactor,
 | 
			
		||||
		Denom:             denom,
 | 
			
		||||
		BorrowLimit:       NewBorrowLimit(hasMaxLimit, maximumLimit, loanToValue),
 | 
			
		||||
		SpotMarketID:      spotMarketID,
 | 
			
		||||
		ConversionFactor:  conversionFactor,
 | 
			
		||||
		InterestRateModel: interestRateModel,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -279,6 +281,10 @@ func (mm MoneyMarket) Validate() error {
 | 
			
		||||
	if err := mm.BorrowLimit.Validate(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := mm.InterestRateModel.Validate(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -295,6 +301,65 @@ func (mms MoneyMarkets) Validate() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InterestRateModel contains information about an asset's interest rate
 | 
			
		||||
type InterestRateModel struct {
 | 
			
		||||
	BaseRateAPY    sdk.Dec `json:"base_rate_apy" yaml:"base_rate_apy"`
 | 
			
		||||
	BaseMultiplier sdk.Dec `json:"base_multiplier" yaml:"base_multiplier"`
 | 
			
		||||
	Kink           sdk.Dec `json:"kink" yaml:"kink"`
 | 
			
		||||
	JumpMultiplier sdk.Dec `json:"jump_multiplier" yaml:"jump_multiplier"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewInterestRateModel returns a new InterestRateModel
 | 
			
		||||
func NewInterestRateModel(baseRateAPY, baseMultiplier, kink, jumpMultiplier sdk.Dec) InterestRateModel {
 | 
			
		||||
	return InterestRateModel{
 | 
			
		||||
		BaseRateAPY:    baseRateAPY,
 | 
			
		||||
		BaseMultiplier: baseMultiplier,
 | 
			
		||||
		Kink:           kink,
 | 
			
		||||
		JumpMultiplier: jumpMultiplier,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Validate InterestRateModel param
 | 
			
		||||
func (irm InterestRateModel) Validate() error {
 | 
			
		||||
	if irm.BaseRateAPY.IsNegative() || irm.BaseRateAPY.GT(sdk.OneDec()) {
 | 
			
		||||
		return fmt.Errorf("Base rate APY must be between 0.0-1.0")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if irm.BaseMultiplier.IsNegative() {
 | 
			
		||||
		return fmt.Errorf("Base multiplier must be positive")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if irm.Kink.IsNegative() || irm.Kink.GT(sdk.OneDec()) {
 | 
			
		||||
		return fmt.Errorf("Kink must be between 0.0-1.0")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if irm.JumpMultiplier.IsNegative() {
 | 
			
		||||
		return fmt.Errorf("Jump multiplier must be positive")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Equal returns a boolean indicating if an InterestRateModel is equal to another InterestRateModel
 | 
			
		||||
func (irm InterestRateModel) Equal(comparisonIRM InterestRateModel) bool {
 | 
			
		||||
	if !irm.BaseRateAPY.Equal(comparisonIRM.BaseRateAPY) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if !irm.BaseMultiplier.Equal(comparisonIRM.BaseMultiplier) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if !irm.Kink.Equal(comparisonIRM.Kink) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	if !irm.JumpMultiplier.Equal(comparisonIRM.JumpMultiplier) {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// InterestRateModels slice of InterestRateModel
 | 
			
		||||
type InterestRateModels []InterestRateModel
 | 
			
		||||
 | 
			
		||||
// NewParams returns a new params object
 | 
			
		||||
func NewParams(active bool, lps DistributionSchedules, dds DelegatorDistributionSchedules, moneyMarkets MoneyMarkets) Params {
 | 
			
		||||
	return Params{
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user