mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-04-04 15:55:23 +00:00 
			
		
		
		
	Fix: Check debt limit when adding cdp (#433)
* fix: check debt limit when opening cdp * fix: increase debt limit for querier tests
This commit is contained in:
		
							parent
							
								
									45e40fe357
								
							
						
					
					
						commit
						55b73e36ee
					
				| @ -27,6 +27,11 @@ func (k Keeper) AddCdp(ctx sdk.Context, owner sdk.AccAddress, collateral sdk.Coi | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	err = k.ValidateDebtLimit(ctx, collateral[0].Denom, principal) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
| 	err = k.ValidateCollateralizationRatio(ctx, collateral, principal, sdk.NewCoins()) | 	err = k.ValidateCollateralizationRatio(ctx, collateral, principal, sdk.NewCoins()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| @ -371,10 +376,18 @@ func (k Keeper) ValidatePrincipalDraw(ctx sdk.Context, principal sdk.Coins) sdk. | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ValidateDebtLimit validates that the input debt amount does not exceed the global debt limit
 | // ValidateDebtLimit validates that the input debt amount does not exceed the global debt limit or the debt limit for that collateral
 | ||||||
| func (k Keeper) ValidateDebtLimit(ctx sdk.Context, collateralDenom string, principal sdk.Coins) sdk.Error { | func (k Keeper) ValidateDebtLimit(ctx sdk.Context, collateralDenom string, principal sdk.Coins) sdk.Error { | ||||||
|  | 	cp, found := k.GetCollateral(ctx, collateralDenom) | ||||||
|  | 	if !found { | ||||||
|  | 		return types.ErrCollateralNotSupported(k.codespace, collateralDenom) | ||||||
|  | 	} | ||||||
| 	for _, dc := range principal { | 	for _, dc := range principal { | ||||||
| 		totalPrincipal := k.GetTotalPrincipal(ctx, collateralDenom, dc.Denom).Add(dc.Amount) | 		totalPrincipal := k.GetTotalPrincipal(ctx, collateralDenom, dc.Denom).Add(dc.Amount) | ||||||
|  | 		collateralLimit := cp.DebtLimit.AmountOf(dc.Denom) | ||||||
|  | 		if totalPrincipal.GT(collateralLimit) { | ||||||
|  | 			return types.ErrExceedsDebtLimit(k.codespace, sdk.NewCoins(sdk.NewCoin(dc.Denom, totalPrincipal)), sdk.NewCoins(sdk.NewCoin(dc.Denom, collateralLimit))) | ||||||
|  | 		} | ||||||
| 		globalLimit := k.GetParams(ctx).GlobalDebtLimit.AmountOf(dc.Denom) | 		globalLimit := k.GetParams(ctx).GlobalDebtLimit.AmountOf(dc.Denom) | ||||||
| 		if totalPrincipal.GT(globalLimit) { | 		if totalPrincipal.GT(globalLimit) { | ||||||
| 			return types.ErrExceedsDebtLimit(k.codespace, sdk.NewCoins(sdk.NewCoin(dc.Denom, totalPrincipal)), sdk.NewCoins(sdk.NewCoin(dc.Denom, globalLimit))) | 			return types.ErrExceedsDebtLimit(k.codespace, sdk.NewCoins(sdk.NewCoin(dc.Denom, totalPrincipal)), sdk.NewCoins(sdk.NewCoin(dc.Denom, globalLimit))) | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ func (suite *CdpTestSuite) SetupTest() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *CdpTestSuite) TestAddCdp() { | func (suite *CdpTestSuite) TestAddCdp() { | ||||||
| 	_, addrs := app.GeneratePrivKeyAddressPairs(1) | 	_, addrs := app.GeneratePrivKeyAddressPairs(2) | ||||||
| 	ak := suite.app.GetAccountKeeper() | 	ak := suite.app.GetAccountKeeper() | ||||||
| 	acc := ak.NewAccountWithAddress(suite.ctx, addrs[0]) | 	acc := ak.NewAccountWithAddress(suite.ctx, addrs[0]) | ||||||
| 	acc.SetCoins(cs(c("xrp", 200000000), c("btc", 500000000))) | 	acc.SetCoins(cs(c("xrp", 200000000), c("btc", 500000000))) | ||||||
| @ -46,14 +46,21 @@ func (suite *CdpTestSuite) TestAddCdp() { | |||||||
| 	err := suite.keeper.AddCdp(suite.ctx, addrs[0], cs(c("xrp", 200000000)), cs(c("usdx", 26000000))) | 	err := suite.keeper.AddCdp(suite.ctx, addrs[0], cs(c("xrp", 200000000)), cs(c("usdx", 26000000))) | ||||||
| 	suite.Equal(types.CodeInvalidCollateralRatio, err.Result().Code) | 	suite.Equal(types.CodeInvalidCollateralRatio, err.Result().Code) | ||||||
| 	err = suite.keeper.AddCdp(suite.ctx, addrs[0], cs(c("xrp", 500000000)), cs(c("usdx", 26000000))) | 	err = suite.keeper.AddCdp(suite.ctx, addrs[0], cs(c("xrp", 500000000)), cs(c("usdx", 26000000))) | ||||||
| 	suite.Error(err) | 	suite.Error(err) // insufficient balance
 | ||||||
| 	err = suite.keeper.AddCdp(suite.ctx, addrs[0], cs(c("xrp", 200000000)), cs(c("xusd", 10000000))) | 	err = suite.keeper.AddCdp(suite.ctx, addrs[0], cs(c("xrp", 200000000)), cs(c("xusd", 10000000))) | ||||||
| 	suite.Equal(types.CodeDebtNotSupported, err.Result().Code) | 	suite.Equal(types.CodeDebtNotSupported, err.Result().Code) | ||||||
|  | 
 | ||||||
|  | 	acc2 := ak.NewAccountWithAddress(suite.ctx, addrs[1]) | ||||||
|  | 	acc2.SetCoins(cs(c("btc", 500000000000))) | ||||||
|  | 	ak.SetAccount(suite.ctx, acc2) | ||||||
|  | 	err = suite.keeper.AddCdp(suite.ctx, addrs[1], cs(c("btc", 500000000000)), cs(c("usdx", 500000000001))) | ||||||
|  | 	suite.Equal(types.CodeExceedsDebtLimit, err.Result().Code) | ||||||
|  | 
 | ||||||
| 	ctx := suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(time.Hour * 2)) | 	ctx := suite.ctx.WithBlockTime(suite.ctx.BlockTime().Add(time.Hour * 2)) | ||||||
| 	pk := suite.app.GetPriceFeedKeeper() | 	pk := suite.app.GetPriceFeedKeeper() | ||||||
| 	_ = pk.SetCurrentPrices(ctx, "xrp:usd") | 	_ = pk.SetCurrentPrices(ctx, "xrp:usd") | ||||||
| 	err = suite.keeper.AddCdp(ctx, addrs[0], cs(c("xrp", 100000000)), cs(c("usdx", 10000000))) | 	err = suite.keeper.AddCdp(ctx, addrs[0], cs(c("xrp", 100000000)), cs(c("usdx", 10000000))) | ||||||
| 	suite.Error(err) | 	suite.Error(err) // no prices in pricefeed
 | ||||||
| 
 | 
 | ||||||
| 	_ = pk.SetCurrentPrices(suite.ctx, "xrp:usd") | 	_ = pk.SetCurrentPrices(suite.ctx, "xrp:usd") | ||||||
| 	err = suite.keeper.AddCdp(suite.ctx, addrs[0], cs(c("xrp", 100000000)), cs(c("usdx", 10000000))) | 	err = suite.keeper.AddCdp(suite.ctx, addrs[0], cs(c("xrp", 100000000)), cs(c("usdx", 10000000))) | ||||||
|  | |||||||
| @ -159,6 +159,64 @@ func NewCDPGenStateMulti() app.GenesisState { | |||||||
| 	return app.GenesisState{cdp.ModuleName: cdp.ModuleCdc.MustMarshalJSON(cdpGenesis)} | 	return app.GenesisState{cdp.ModuleName: cdp.ModuleCdc.MustMarshalJSON(cdpGenesis)} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func NewCDPGenStateHighDebtLimit() app.GenesisState { | ||||||
|  | 	cdpGenesis := cdp.GenesisState{ | ||||||
|  | 		Params: cdp.Params{ | ||||||
|  | 			GlobalDebtLimit:              sdk.NewCoins(sdk.NewInt64Coin("usdx", 100000000000000), sdk.NewInt64Coin("susd", 100000000000000)), | ||||||
|  | 			SurplusAuctionThreshold:      cdp.DefaultSurplusThreshold, | ||||||
|  | 			DebtAuctionThreshold:         cdp.DefaultDebtThreshold, | ||||||
|  | 			SavingsDistributionFrequency: cdp.DefaultSavingsDistributionFrequency, | ||||||
|  | 			CollateralParams: cdp.CollateralParams{ | ||||||
|  | 				{ | ||||||
|  | 					Denom:              "xrp", | ||||||
|  | 					LiquidationRatio:   sdk.MustNewDecFromStr("2.0"), | ||||||
|  | 					DebtLimit:          sdk.NewCoins(sdk.NewInt64Coin("usdx", 50000000000000), sdk.NewInt64Coin("susd", 50000000000000)), | ||||||
|  | 					StabilityFee:       sdk.MustNewDecFromStr("1.000000001547125958"), // %5 apr
 | ||||||
|  | 					LiquidationPenalty: d("0.05"), | ||||||
|  | 					AuctionSize:        i(7000000000), | ||||||
|  | 					Prefix:             0x20, | ||||||
|  | 					MarketID:           "xrp:usd", | ||||||
|  | 					ConversionFactor:   i(6), | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					Denom:              "btc", | ||||||
|  | 					LiquidationRatio:   sdk.MustNewDecFromStr("1.5"), | ||||||
|  | 					DebtLimit:          sdk.NewCoins(sdk.NewInt64Coin("usdx", 50000000000000), sdk.NewInt64Coin("susd", 50000000000000)), | ||||||
|  | 					StabilityFee:       sdk.MustNewDecFromStr("1.000000000782997609"), // %2.5 apr
 | ||||||
|  | 					LiquidationPenalty: d("0.025"), | ||||||
|  | 					AuctionSize:        i(10000000), | ||||||
|  | 					Prefix:             0x21, | ||||||
|  | 					MarketID:           "btc:usd", | ||||||
|  | 					ConversionFactor:   i(8), | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			DebtParams: cdp.DebtParams{ | ||||||
|  | 				{ | ||||||
|  | 					Denom:            "usdx", | ||||||
|  | 					ReferenceAsset:   "usd", | ||||||
|  | 					ConversionFactor: i(6), | ||||||
|  | 					DebtFloor:        i(10000000), | ||||||
|  | 					SavingsRate:      d("0.95"), | ||||||
|  | 				}, | ||||||
|  | 				{ | ||||||
|  | 					Denom:            "susd", | ||||||
|  | 					ReferenceAsset:   "usd", | ||||||
|  | 					ConversionFactor: i(6), | ||||||
|  | 					DebtFloor:        i(10000000), | ||||||
|  | 					SavingsRate:      d("0.95"), | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 		StartingCdpID:            cdp.DefaultCdpStartingID, | ||||||
|  | 		DebtDenom:                cdp.DefaultDebtDenom, | ||||||
|  | 		GovDenom:                 cdp.DefaultGovDenom, | ||||||
|  | 		CDPs:                     cdp.CDPs{}, | ||||||
|  | 		PreviousBlockTime:        cdp.DefaultPreviousBlockTime, | ||||||
|  | 		PreviousDistributionTime: cdp.DefaultPreviousDistributionTime, | ||||||
|  | 	} | ||||||
|  | 	return app.GenesisState{cdp.ModuleName: cdp.ModuleCdc.MustMarshalJSON(cdpGenesis)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func cdps() (cdps cdp.CDPs) { | func cdps() (cdps cdp.CDPs) { | ||||||
| 	_, addrs := app.GeneratePrivKeyAddressPairs(3) | 	_, addrs := app.GeneratePrivKeyAddressPairs(3) | ||||||
| 	c1 := cdp.NewCDP(uint64(1), addrs[0], sdk.NewCoins(sdk.NewCoin("xrp", sdk.NewInt(10000000))), sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(8000000))), tmtime.Canonical(time.Now())) | 	c1 := cdp.NewCDP(uint64(1), addrs[0], sdk.NewCoins(sdk.NewCoin("xrp", sdk.NewInt(10000000))), sdk.NewCoins(sdk.NewCoin("usdx", sdk.NewInt(8000000))), tmtime.Canonical(time.Now())) | ||||||
|  | |||||||
| @ -53,7 +53,7 @@ func (suite *QuerierTestSuite) SetupTest() { | |||||||
| 	tApp.InitializeFromGenesisStates( | 	tApp.InitializeFromGenesisStates( | ||||||
| 		authGS, | 		authGS, | ||||||
| 		NewPricefeedGenStateMulti(), | 		NewPricefeedGenStateMulti(), | ||||||
| 		NewCDPGenStateMulti(), | 		NewCDPGenStateHighDebtLimit(), | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	suite.ctx = ctx | 	suite.ctx = ctx | ||||||
| @ -93,11 +93,13 @@ func (suite *QuerierTestSuite) SetupTest() { | |||||||
| 			amount = simulation.RandIntBetween(rand.New(rand.NewSource(int64(j))), 500000000, 5000000000) | 			amount = simulation.RandIntBetween(rand.New(rand.NewSource(int64(j))), 500000000, 5000000000) | ||||||
| 			debt = simulation.RandIntBetween(rand.New(rand.NewSource(int64(j))), 1000000000, 25000000000) | 			debt = simulation.RandIntBetween(rand.New(rand.NewSource(int64(j))), 1000000000, 25000000000) | ||||||
| 		} | 		} | ||||||
| 		suite.Nil(suite.keeper.AddCdp(suite.ctx, addrs[j], cs(c(collateral, int64(amount))), cs(c("usdx", int64(debt))))) | 		err = suite.keeper.AddCdp(suite.ctx, addrs[j], cs(c(collateral, int64(amount))), cs(c("usdx", int64(debt)))) | ||||||
|  | 		suite.NoError(err) | ||||||
| 		c, f := suite.keeper.GetCDP(suite.ctx, collateral, uint64(j+1)) | 		c, f := suite.keeper.GetCDP(suite.ctx, collateral, uint64(j+1)) | ||||||
| 		suite.True(f) | 		suite.True(f) | ||||||
| 		cdps[j] = c | 		cdps[j] = c | ||||||
| 		aCDP, _ := suite.keeper.LoadAugmentedCDP(suite.ctx, c) | 		aCDP, err := suite.keeper.LoadAugmentedCDP(suite.ctx, c) | ||||||
|  | 		suite.NoError(err) | ||||||
| 		augmentedCDPs[j] = aCDP | 		augmentedCDPs[j] = aCDP | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -250,7 +252,7 @@ func (suite *QuerierTestSuite) TestQueryParams() { | |||||||
| 	var p types.Params | 	var p types.Params | ||||||
| 	suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &p)) | 	suite.Nil(types.ModuleCdc.UnmarshalJSON(bz, &p)) | ||||||
| 
 | 
 | ||||||
| 	cdpGS := NewCDPGenStateMulti() | 	cdpGS := NewCDPGenStateHighDebtLimit() | ||||||
| 	gs := types.GenesisState{} | 	gs := types.GenesisState{} | ||||||
| 	types.ModuleCdc.UnmarshalJSON(cdpGS["cdp"], &gs) | 	types.ModuleCdc.UnmarshalJSON(cdpGS["cdp"], &gs) | ||||||
| 	suite.Equal(gs.Params, p) | 	suite.Equal(gs.Params, p) | ||||||
|  | |||||||
| @ -79,7 +79,7 @@ func randomCdpGenState(selection int) types.GenesisState { | |||||||
| 						DebtLimit:          sdk.NewCoins(sdk.NewInt64Coin("usdx", 20000000000000)), | 						DebtLimit:          sdk.NewCoins(sdk.NewInt64Coin("usdx", 20000000000000)), | ||||||
| 						StabilityFee:       sdk.MustNewDecFromStr("1.000000004431822130"), | 						StabilityFee:       sdk.MustNewDecFromStr("1.000000004431822130"), | ||||||
| 						LiquidationPenalty: sdk.MustNewDecFromStr("0.075"), | 						LiquidationPenalty: sdk.MustNewDecFromStr("0.075"), | ||||||
| 						AuctionSize:        sdk.NewInt(10000000000), | 						AuctionSize:        sdk.NewInt(100000000000), | ||||||
| 						Prefix:             0x20, | 						Prefix:             0x20, | ||||||
| 						MarketID:           "xrp:usd", | 						MarketID:           "xrp:usd", | ||||||
| 						ConversionFactor:   sdk.NewInt(6), | 						ConversionFactor:   sdk.NewInt(6), | ||||||
| @ -90,7 +90,7 @@ func randomCdpGenState(selection int) types.GenesisState { | |||||||
| 						DebtLimit:          sdk.NewCoins(sdk.NewInt64Coin("usdx", 50000000000000)), | 						DebtLimit:          sdk.NewCoins(sdk.NewInt64Coin("usdx", 50000000000000)), | ||||||
| 						StabilityFee:       sdk.MustNewDecFromStr("1.000000000782997609"), | 						StabilityFee:       sdk.MustNewDecFromStr("1.000000000782997609"), | ||||||
| 						LiquidationPenalty: sdk.MustNewDecFromStr("0.05"), | 						LiquidationPenalty: sdk.MustNewDecFromStr("0.05"), | ||||||
| 						AuctionSize:        sdk.NewInt(50000000), | 						AuctionSize:        sdk.NewInt(1000000000), | ||||||
| 						Prefix:             0x21, | 						Prefix:             0x21, | ||||||
| 						MarketID:           "btc:usd", | 						MarketID:           "btc:usd", | ||||||
| 						ConversionFactor:   sdk.NewInt(8), | 						ConversionFactor:   sdk.NewInt(8), | ||||||
| @ -101,7 +101,7 @@ func randomCdpGenState(selection int) types.GenesisState { | |||||||
| 						DebtLimit:          sdk.NewCoins(sdk.NewInt64Coin("usdx", 30000000000000)), | 						DebtLimit:          sdk.NewCoins(sdk.NewInt64Coin("usdx", 30000000000000)), | ||||||
| 						StabilityFee:       sdk.MustNewDecFromStr("1.000000002293273137"), | 						StabilityFee:       sdk.MustNewDecFromStr("1.000000002293273137"), | ||||||
| 						LiquidationPenalty: sdk.MustNewDecFromStr("0.15"), | 						LiquidationPenalty: sdk.MustNewDecFromStr("0.15"), | ||||||
| 						AuctionSize:        sdk.NewInt(10000000000), | 						AuctionSize:        sdk.NewInt(1000000000000), | ||||||
| 						Prefix:             0x22, | 						Prefix:             0x22, | ||||||
| 						MarketID:           "bnb:usd", | 						MarketID:           "bnb:usd", | ||||||
| 						ConversionFactor:   sdk.NewInt(8), | 						ConversionFactor:   sdk.NewInt(8), | ||||||
|  | |||||||
| @ -52,9 +52,9 @@ func SimulateMsgCdp(ak auth.AccountKeeper, k cdp.Keeper, pfk pricefeed.Keeper) s | |||||||
| 			minCollateralDeposit = ShiftDec(minCollateralDeposit, randCollateralParam.ConversionFactor) | 			minCollateralDeposit = ShiftDec(minCollateralDeposit, randCollateralParam.ConversionFactor) | ||||||
| 			// convert to integer and always round up
 | 			// convert to integer and always round up
 | ||||||
| 			minCollateralDepositRounded := minCollateralDeposit.TruncateInt().Add(sdk.OneInt()) | 			minCollateralDepositRounded := minCollateralDeposit.TruncateInt().Add(sdk.OneInt()) | ||||||
| 			// if the account has less than the min deposit, return
 |  | ||||||
| 			if coins.AmountOf(randCollateralParam.Denom).LT(minCollateralDepositRounded) { | 			if coins.AmountOf(randCollateralParam.Denom).LT(minCollateralDepositRounded) { | ||||||
| 				return simulation.NoOpMsg(cdp.ModuleName), nil, nil | 				// account doesn't have enough funds to open a cdp for the min debt amount
 | ||||||
|  | 				return simulation.NewOperationMsgBasic(cdp.ModuleName, "no-operation", "insufficient funds to open cdp", false, nil), nil, nil | ||||||
| 			} | 			} | ||||||
| 			// set the max collateral deposit to the amount of coins in the account
 | 			// set the max collateral deposit to the amount of coins in the account
 | ||||||
| 			maxCollateralDeposit := coins.AmountOf(randCollateralParam.Denom) | 			maxCollateralDeposit := coins.AmountOf(randCollateralParam.Denom) | ||||||
| @ -65,6 +65,14 @@ func SimulateMsgCdp(ak auth.AccountKeeper, k cdp.Keeper, pfk pricefeed.Keeper) s | |||||||
| 			collateralDepositValue := ShiftDec(sdk.NewDecFromInt(collateralDeposit), randCollateralParam.ConversionFactor.Neg()).Mul(priceShifted) | 			collateralDepositValue := ShiftDec(sdk.NewDecFromInt(collateralDeposit), randCollateralParam.ConversionFactor.Neg()).Mul(priceShifted) | ||||||
| 			// calculate the max amount of debt that could be drawn for the chosen deposit
 | 			// calculate the max amount of debt that could be drawn for the chosen deposit
 | ||||||
| 			maxDebtDraw := collateralDepositValue.Quo(randCollateralParam.LiquidationRatio).TruncateInt() | 			maxDebtDraw := collateralDepositValue.Quo(randCollateralParam.LiquidationRatio).TruncateInt() | ||||||
|  | 			// check that the debt limit hasn't been reached
 | ||||||
|  | 			availableAssetDebt := randCollateralParam.DebtLimit.AmountOf(randDebtParam.Denom).Sub(k.GetTotalPrincipal(ctx, randCollateralParam.Denom, randDebtParam.Denom)) | ||||||
|  | 			if availableAssetDebt.LTE(randDebtParam.DebtFloor) { | ||||||
|  | 				// debt limit has been reached
 | ||||||
|  | 				return simulation.NewOperationMsgBasic(cdp.ModuleName, "no-operation", "debt limit reached, cannot open cdp", false, nil), nil, nil | ||||||
|  | 			} | ||||||
|  | 			// ensure that the debt draw does not exceed the debt limit
 | ||||||
|  | 			maxDebtDraw = sdk.MinInt(maxDebtDraw, availableAssetDebt) | ||||||
| 			// randomly select a debt draw amount
 | 			// randomly select a debt draw amount
 | ||||||
| 			debtDraw := sdk.NewInt(int64(simulation.RandIntBetween(r, int(randDebtParam.DebtFloor.Int64()), int(maxDebtDraw.Int64())))) | 			debtDraw := sdk.NewInt(int64(simulation.RandIntBetween(r, int(randDebtParam.DebtFloor.Int64()), int(maxDebtDraw.Int64())))) | ||||||
| 			msg := cdp.NewMsgCreateCDP(acc.GetAddress(), sdk.NewCoins(sdk.NewCoin(randCollateralParam.Denom, collateralDeposit)), sdk.NewCoins(sdk.NewCoin(randDebtParam.Denom, debtDraw))) | 			msg := cdp.NewMsgCreateCDP(acc.GetAddress(), sdk.NewCoins(sdk.NewCoin(randCollateralParam.Denom, collateralDeposit)), sdk.NewCoins(sdk.NewCoin(randDebtParam.Denom, debtDraw))) | ||||||
| @ -114,10 +122,23 @@ func SimulateMsgCdp(ak auth.AccountKeeper, k cdp.Keeper, pfk pricefeed.Keeper) s | |||||||
| 		if shouldDraw(r) { | 		if shouldDraw(r) { | ||||||
| 			collateralShifted := ShiftDec(sdk.NewDecFromInt(existingCDP.Collateral.AmountOf(randCollateralParam.Denom)), randCollateralParam.ConversionFactor.Neg()) | 			collateralShifted := ShiftDec(sdk.NewDecFromInt(existingCDP.Collateral.AmountOf(randCollateralParam.Denom)), randCollateralParam.ConversionFactor.Neg()) | ||||||
| 			collateralValue := collateralShifted.Mul(priceShifted) | 			collateralValue := collateralShifted.Mul(priceShifted) | ||||||
|  | 			// given the current collateral value, calculate how much debt we could add while maintaining a valid liquidation ratio
 | ||||||
| 			debt := (existingCDP.Principal.Add(existingCDP.AccumulatedFees)).AmountOf(randDebtParam.Denom) | 			debt := (existingCDP.Principal.Add(existingCDP.AccumulatedFees)).AmountOf(randDebtParam.Denom) | ||||||
| 			maxTotalDebt := collateralValue.Quo(randCollateralParam.LiquidationRatio) | 			maxTotalDebt := collateralValue.Quo(randCollateralParam.LiquidationRatio) | ||||||
| 			maxDebt := maxTotalDebt.Sub(sdk.NewDecFromInt(debt)).TruncateInt().Sub(sdk.OneInt()) | 			maxDebt := maxTotalDebt.Sub(sdk.NewDecFromInt(debt)).TruncateInt() | ||||||
| 			randDrawAmount := sdk.NewInt(int64(simulation.RandIntBetween(r, 1, int(maxDebt.Int64())))) | 			if maxDebt.LTE(sdk.OneInt()) { | ||||||
|  | 				// debt in cdp is maxed out
 | ||||||
|  | 				return simulation.NewOperationMsgBasic(cdp.ModuleName, "no-operation", "cdp debt maxed out, cannot draw more debt", false, nil), nil, nil | ||||||
|  | 			} | ||||||
|  | 			// check if the debt limit has been reached
 | ||||||
|  | 			availableAssetDebt := randCollateralParam.DebtLimit.AmountOf(randDebtParam.Denom).Sub(k.GetTotalPrincipal(ctx, randCollateralParam.Denom, randDebtParam.Denom)) | ||||||
|  | 			if availableAssetDebt.LTE(sdk.OneInt()) { | ||||||
|  | 				// debt limit has been reached
 | ||||||
|  | 				return simulation.NewOperationMsgBasic(cdp.ModuleName, "no-operation", "debt limit reached, cannot draw more debt", false, nil), nil, nil | ||||||
|  | 			} | ||||||
|  | 			maxDraw := sdk.MinInt(maxDebt, availableAssetDebt) | ||||||
|  | 
 | ||||||
|  | 			randDrawAmount := sdk.NewInt(int64(simulation.RandIntBetween(r, 1, int(maxDraw.Int64())))) | ||||||
| 			msg := cdp.NewMsgDrawDebt(acc.GetAddress(), randCollateralParam.Denom, sdk.NewCoins(sdk.NewCoin(randDebtParam.Denom, randDrawAmount))) | 			msg := cdp.NewMsgDrawDebt(acc.GetAddress(), randCollateralParam.Denom, sdk.NewCoins(sdk.NewCoin(randDebtParam.Denom, randDrawAmount))) | ||||||
| 			err := msg.ValidateBasic() | 			err := msg.ValidateBasic() | ||||||
| 			if err != nil { | 			if err != nil { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Kevin Davis
						Kevin Davis