mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 15:25:18 +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.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.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.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/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 v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
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.ApplyDelegationRewards(ctx, k.BondDenom(ctx))
|
||||||
k.SetPreviousDelegationDistribution(ctx, ctx.BlockTime(), k.BondDenom(ctx))
|
k.SetPreviousDelegationDistribution(ctx, ctx.BlockTime(), k.BondDenom(ctx))
|
||||||
}
|
}
|
||||||
|
k.ApplyInterestRateUpdates(ctx)
|
||||||
k.SetPreviousBlockTime(ctx, ctx.BlockTime())
|
k.SetPreviousBlockTime(ctx, ctx.BlockTime())
|
||||||
}
|
}
|
||||||
|
@ -275,12 +275,12 @@ func (suite *KeeperTestSuite) TestBorrow() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
types.MoneyMarkets{
|
types.MoneyMarkets{
|
||||||
types.NewMoneyMarket("usdx", true, tc.args.usdxBorrowLimit, sdk.MustNewDecFromStr("1"), "usdx:usd", sdk.NewInt(USDX_CF)),
|
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.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.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.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.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.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)
|
), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
|
||||||
|
|
||||||
|
@ -265,8 +265,8 @@ func (suite *KeeperTestSuite) TestClaim() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
types.MoneyMarkets{
|
types.MoneyMarkets{
|
||||||
types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx: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.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)
|
), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
|
||||||
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
||||||
|
@ -108,8 +108,8 @@ func (suite *KeeperTestSuite) TestDeposit() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
types.MoneyMarkets{
|
types.MoneyMarkets{
|
||||||
types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx: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.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)
|
), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
|
||||||
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
||||||
@ -251,8 +251,8 @@ func (suite *KeeperTestSuite) TestWithdraw() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
types.MoneyMarkets{
|
types.MoneyMarkets{
|
||||||
types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx: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.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)
|
), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
|
||||||
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
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)
|
k.cdc.MustUnmarshalBinaryBare(bz, &borrowedCoins)
|
||||||
return borrowedCoins, true
|
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
|
package keeper_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
@ -153,6 +154,51 @@ func (suite *KeeperTestSuite) TestGetSetDeleteClaim() {
|
|||||||
suite.Require().False(f)
|
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 {
|
func (suite *KeeperTestSuite) getAccount(addr sdk.AccAddress) authexported.Account {
|
||||||
ak := suite.app.GetAccountKeeper()
|
ak := suite.app.GetAccountKeeper()
|
||||||
return ak.GetAccount(suite.ctx, addr)
|
return ak.GetAccount(suite.ctx, addr)
|
||||||
|
@ -75,8 +75,8 @@ func (suite *KeeperTestSuite) TestApplyDepositRewards() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
types.MoneyMarkets{
|
types.MoneyMarkets{
|
||||||
types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx: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.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)
|
), tc.args.previousBlockTime, types.DefaultDistributionTimes)
|
||||||
tApp.InitializeFromGenesisStates(app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
tApp.InitializeFromGenesisStates(app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
||||||
@ -443,8 +443,8 @@ func harvestGenesisState(rewardRate sdk.Coin) app.GenesisState {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
types.MoneyMarkets{
|
types.MoneyMarkets{
|
||||||
types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx: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.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.DefaultPreviousBlockTime,
|
||||||
|
@ -291,8 +291,8 @@ func (suite *KeeperTestSuite) TestSendTimeLockedCoinsToAccount() {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
types.MoneyMarkets{
|
types.MoneyMarkets{
|
||||||
types.NewMoneyMarket("usdx", false, sdk.NewDec(1000000000000000), loanToValue, "usdx: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.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)
|
), types.DefaultPreviousBlockTime, types.DefaultDistributionTimes)
|
||||||
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{types.ModuleName: types.ModuleCdc.MustMarshalJSON(harvestGS)})
|
||||||
|
@ -37,6 +37,7 @@ var (
|
|||||||
ClaimsKeyPrefix = []byte{0x04}
|
ClaimsKeyPrefix = []byte{0x04}
|
||||||
BorrowsKeyPrefix = []byte{0x05}
|
BorrowsKeyPrefix = []byte{0x05}
|
||||||
BorrowedCoinsPrefix = []byte{0x06}
|
BorrowedCoinsPrefix = []byte{0x06}
|
||||||
|
InterestRateModelsPrefix = []byte{0x07}
|
||||||
sep = []byte(":")
|
sep = []byte(":")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -253,20 +253,22 @@ func (bl BorrowLimit) Validate() error {
|
|||||||
|
|
||||||
// MoneyMarket is a money market for an individual asset
|
// MoneyMarket is a money market for an individual asset
|
||||||
type MoneyMarket struct {
|
type MoneyMarket struct {
|
||||||
Denom string `json:"denom" yaml:"denom"`
|
Denom string `json:"denom" yaml:"denom"`
|
||||||
BorrowLimit BorrowLimit `json:"borrow_limit" yaml:"borrow_limit"`
|
BorrowLimit BorrowLimit `json:"borrow_limit" yaml:"borrow_limit"`
|
||||||
SpotMarketID string `json:"spot_market_id" yaml:"spot_market_id"`
|
SpotMarketID string `json:"spot_market_id" yaml:"spot_market_id"`
|
||||||
ConversionFactor sdk.Int `json:"conversion_factor" yaml:"conversion_factor"`
|
ConversionFactor sdk.Int `json:"conversion_factor" yaml:"conversion_factor"`
|
||||||
|
InterestRateModel InterestRateModel `json:"interest_rate_model" yaml:"interest_rate_model"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMoneyMarket returns a new MoneyMarket
|
// NewMoneyMarket returns a new MoneyMarket
|
||||||
func NewMoneyMarket(denom string, hasMaxLimit bool, maximumLimit, loanToValue sdk.Dec,
|
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{
|
return MoneyMarket{
|
||||||
Denom: denom,
|
Denom: denom,
|
||||||
BorrowLimit: NewBorrowLimit(hasMaxLimit, maximumLimit, loanToValue),
|
BorrowLimit: NewBorrowLimit(hasMaxLimit, maximumLimit, loanToValue),
|
||||||
SpotMarketID: spotMarketID,
|
SpotMarketID: spotMarketID,
|
||||||
ConversionFactor: conversionFactor,
|
ConversionFactor: conversionFactor,
|
||||||
|
InterestRateModel: interestRateModel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +281,10 @@ func (mm MoneyMarket) Validate() error {
|
|||||||
if err := mm.BorrowLimit.Validate(); err != nil {
|
if err := mm.BorrowLimit.Validate(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := mm.InterestRateModel.Validate(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,6 +301,65 @@ func (mms MoneyMarkets) Validate() error {
|
|||||||
return nil
|
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
|
// NewParams returns a new params object
|
||||||
func NewParams(active bool, lps DistributionSchedules, dds DelegatorDistributionSchedules, moneyMarkets MoneyMarkets) Params {
|
func NewParams(active bool, lps DistributionSchedules, dds DelegatorDistributionSchedules, moneyMarkets MoneyMarkets) Params {
|
||||||
return Params{
|
return Params{
|
||||||
|
Loading…
Reference in New Issue
Block a user