mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-23 23:05: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.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