mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-04-04 15:55:23 +00:00 
			
		
		
		
	tidy up cdp tests
This commit is contained in:
		
							parent
							
								
									2152bb4ed2
								
							
						
					
					
						commit
						81302ce29f
					
				| @ -2,7 +2,6 @@ package cdp_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/cosmos/cosmos-sdk/simapp" | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| @ -10,7 +9,6 @@ import ( | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	"github.com/kava-labs/kava/x/cdp" | ||||
| 	"github.com/kava-labs/kava/x/pricefeed" | ||||
| ) | ||||
| 
 | ||||
| func TestApp_CreateModifyDeleteCDP(t *testing.T) { | ||||
| @ -21,40 +19,13 @@ func TestApp_CreateModifyDeleteCDP(t *testing.T) { | ||||
| 	testPrivKey := privKeys[0] | ||||
| 	tApp.InitializeFromGenesisStates( | ||||
| 		app.NewAuthGenState(addrs, []sdk.Coins{cs(c("xrp", 100))}), | ||||
| 		NewPFGenState("xrp", d("1.00")), | ||||
| 		NewCDPGenState("xrp", d("1.5")), | ||||
| 	) | ||||
| 	ctx := tApp.NewContext(false, abci.Header{}) | ||||
| 	// check balance
 | ||||
| 	ctx := tApp.NewContext(false, abci.Header{}) | ||||
| 	tApp.CheckBalance(t, ctx, testAddr, cs(c("xrp", 100))) | ||||
| 
 | ||||
| 	// setup cdp keeper
 | ||||
| 	keeper := tApp.GetCDPKeeper() | ||||
| 	params := cdp.CdpParams{ | ||||
| 		GlobalDebtLimit: sdk.NewInt(100000), | ||||
| 		CollateralParams: []cdp.CollateralParams{ | ||||
| 			{ | ||||
| 				Denom:            "xrp", | ||||
| 				LiquidationRatio: sdk.MustNewDecFromStr("1.5"), | ||||
| 				DebtLimit:        sdk.NewInt(10000), | ||||
| 			}, | ||||
| 		}, | ||||
| 		StableDenoms: []string{"usdx"}, | ||||
| 	} | ||||
| 	keeper.SetParams(ctx, params) | ||||
| 	keeper.SetGlobalDebt(ctx, sdk.NewInt(0)) | ||||
| 	pricefeedKeeper := tApp.GetPriceFeedKeeper() | ||||
| 	ap := pricefeed.Params{ | ||||
| 		Markets: []pricefeed.Market{ | ||||
| 			pricefeed.Market{ | ||||
| 				MarketID: "xrp", BaseAsset: "xrp", | ||||
| 				QuoteAsset: "usd", Oracles: pricefeed.Oracles{}, Active: true}, | ||||
| 		}, | ||||
| 	} | ||||
| 	pricefeedKeeper.SetParams(ctx, ap) | ||||
| 	pricefeedKeeper.SetPrice( | ||||
| 		ctx, sdk.AccAddress{}, "xrp", | ||||
| 		sdk.MustNewDecFromStr("1.00"), | ||||
| 		time.Unix(9999999999, 0)) // some deterministic future date
 | ||||
| 	pricefeedKeeper.SetCurrentPrices(ctx, "xrp") | ||||
| 	tApp.EndBlock(abci.RequestEndBlock{}) | ||||
| 	tApp.Commit() | ||||
| 
 | ||||
|  | ||||
| @ -1,7 +1,13 @@ | ||||
| package cdp_test | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/x/cdp" | ||||
| 	"github.com/kava-labs/kava/x/pricefeed" | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| ) | ||||
| 
 | ||||
| // Avoid cluttering test cases with long function name
 | ||||
| @ -9,3 +15,42 @@ func i(in int64) sdk.Int                    { return sdk.NewInt(in) } | ||||
| func d(str string) sdk.Dec                  { return sdk.MustNewDecFromStr(str) } | ||||
| func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) } | ||||
| func cs(coins ...sdk.Coin) sdk.Coins        { return sdk.NewCoins(coins...) } | ||||
| 
 | ||||
| func NewPFGenState(asset string, price sdk.Dec) app.GenesisState { | ||||
| 	quote := "usd" | ||||
| 	ap := pricefeed.Params{ | ||||
| 		Markets: []pricefeed.Market{ | ||||
| 			pricefeed.Market{MarketID: asset, BaseAsset: asset, QuoteAsset: quote, Oracles: pricefeed.Oracles{}, Active: true}, | ||||
| 		}, | ||||
| 	} | ||||
| 	pfGenesis := pricefeed.GenesisState{ | ||||
| 		Params: ap, | ||||
| 		PostedPrices: []pricefeed.PostedPrice{ | ||||
| 			pricefeed.PostedPrice{ | ||||
| 				MarketID:      asset, | ||||
| 				OracleAddress: sdk.AccAddress{}, | ||||
| 				Price:         price, | ||||
| 				Expiry:        time.Unix(9999999999, 0), // some deterministic future date,
 | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	return app.GenesisState{pricefeed.ModuleName: pricefeed.ModuleCdc.MustMarshalJSON(pfGenesis)} | ||||
| } | ||||
| 
 | ||||
| func NewCDPGenState(asset string, liquidationRatio sdk.Dec) app.GenesisState { | ||||
| 	cdpGenesis := cdp.GenesisState{ | ||||
| 		Params: cdp.CdpParams{ | ||||
| 			GlobalDebtLimit: sdk.NewInt(1000000), | ||||
| 			CollateralParams: []cdp.CollateralParams{ | ||||
| 				{ | ||||
| 					Denom:            asset, | ||||
| 					LiquidationRatio: liquidationRatio, | ||||
| 					DebtLimit:        sdk.NewInt(500000), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		GlobalDebt: sdk.ZeroInt(), | ||||
| 		CDPs:       cdp.CDPs{}, | ||||
| 	} | ||||
| 	return app.GenesisState{cdp.ModuleName: cdp.ModuleCdc.MustMarshalJSON(cdpGenesis)} | ||||
| } | ||||
| @ -35,8 +35,9 @@ func TestKeeper_AddSubtractGetCoins(t *testing.T) { | ||||
| 		t.Run(tc.name, func(t *testing.T) { | ||||
| 			// setup app with an account
 | ||||
| 			tApp := app.NewTestApp() | ||||
| 			authGenState := app.NewAuthGenState([]sdk.AccAddress{normalAddr}, []sdk.Coins{cs(c("usdx", 100), c("kava", 100))}) | ||||
| 			tApp.InitializeFromGenesisStates(authGenState) | ||||
| 			tApp.InitializeFromGenesisStates( | ||||
| 				app.NewAuthGenState([]sdk.AccAddress{normalAddr}, []sdk.Coins{cs(c("usdx", 100), c("kava", 100))}), | ||||
| 			) | ||||
| 
 | ||||
| 			// create a new context and setup the liquidator account
 | ||||
| 			ctx := tApp.NewContext(false, abci.Header{}) | ||||
|  | ||||
| @ -1,9 +1,14 @@ | ||||
| package keeper_test | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| 
 | ||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	"github.com/kava-labs/kava/x/cdp" | ||||
| 	"github.com/kava-labs/kava/x/cdp/types" | ||||
| 	"github.com/kava-labs/kava/x/pricefeed" | ||||
| ) | ||||
| 
 | ||||
| // Avoid cluttering test cases with long function name
 | ||||
| @ -12,35 +17,91 @@ func d(str string) sdk.Dec                  { return sdk.MustNewDecFromStr(str) | ||||
| func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amount) } | ||||
| func cs(coins ...sdk.Coin) sdk.Coins        { return sdk.NewCoins(coins...) } | ||||
| 
 | ||||
| func defaultParamsMulti() types.CdpParams { | ||||
| 	return types.CdpParams{ | ||||
| 		GlobalDebtLimit: sdk.NewInt(1000000), | ||||
| 		CollateralParams: []types.CollateralParams{ | ||||
| 			{ | ||||
| 				Denom:            "btc", | ||||
| 				LiquidationRatio: sdk.MustNewDecFromStr("1.5"), | ||||
| 				DebtLimit:        sdk.NewInt(500000), | ||||
| 			}, | ||||
| 			{ | ||||
| 				Denom:            "xrp", | ||||
| 				LiquidationRatio: sdk.MustNewDecFromStr("2.0"), | ||||
| 				DebtLimit:        sdk.NewInt(500000), | ||||
| func NewPFGenState(asset string, price sdk.Dec) app.GenesisState { | ||||
| 	quote := "usd" | ||||
| 	ap := pricefeed.Params{ | ||||
| 		Markets: []pricefeed.Market{ | ||||
| 			pricefeed.Market{MarketID: asset, BaseAsset: asset, QuoteAsset: quote, Oracles: pricefeed.Oracles{}, Active: true}, | ||||
| 		}, | ||||
| 	} | ||||
| 	pfGenesis := pricefeed.GenesisState{ | ||||
| 		Params: ap, | ||||
| 		PostedPrices: []pricefeed.PostedPrice{ | ||||
| 			pricefeed.PostedPrice{ | ||||
| 				MarketID:      asset, | ||||
| 				OracleAddress: sdk.AccAddress{}, | ||||
| 				Price:         price, | ||||
| 				Expiry:        time.Unix(9999999999, 0), // some deterministic future date,
 | ||||
| 			}, | ||||
| 		}, | ||||
| 		StableDenoms: []string{"usdx"}, | ||||
| 	} | ||||
| 	return app.GenesisState{pricefeed.ModuleName: pricefeed.ModuleCdc.MustMarshalJSON(pfGenesis)} | ||||
| } | ||||
| 
 | ||||
| func defaultParamsSingle() types.CdpParams { | ||||
| 	return types.CdpParams{ | ||||
| 		GlobalDebtLimit: sdk.NewInt(1000000), | ||||
| 		CollateralParams: []types.CollateralParams{ | ||||
| 			{ | ||||
| 				Denom:            "xrp", | ||||
| 				LiquidationRatio: sdk.MustNewDecFromStr("2.0"), | ||||
| 				DebtLimit:        sdk.NewInt(500000), | ||||
| func NewCDPGenState(asset string, liquidationRatio sdk.Dec) app.GenesisState { | ||||
| 	cdpGenesis := cdp.GenesisState{ | ||||
| 		Params: cdp.CdpParams{ | ||||
| 			GlobalDebtLimit: sdk.NewInt(1000000), | ||||
| 			CollateralParams: []cdp.CollateralParams{ | ||||
| 				{ | ||||
| 					Denom:            asset, | ||||
| 					LiquidationRatio: liquidationRatio, | ||||
| 					DebtLimit:        sdk.NewInt(500000), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		StableDenoms: []string{"usdx"}, | ||||
| 		GlobalDebt: sdk.ZeroInt(), | ||||
| 		CDPs:       cdp.CDPs{}, | ||||
| 	} | ||||
| 	return app.GenesisState{cdp.ModuleName: cdp.ModuleCdc.MustMarshalJSON(cdpGenesis)} | ||||
| } | ||||
| 
 | ||||
| func NewPFGenStateMulti() app.GenesisState { | ||||
| 	quote := "usd" | ||||
| 	ap := pricefeed.Params{ | ||||
| 		Markets: []pricefeed.Market{ | ||||
| 			pricefeed.Market{MarketID: "btc", BaseAsset: "btc", QuoteAsset: quote, Oracles: pricefeed.Oracles{}, Active: true}, | ||||
| 			pricefeed.Market{MarketID: "xrp", BaseAsset: "xrp", QuoteAsset: quote, Oracles: pricefeed.Oracles{}, Active: true}, | ||||
| 		}, | ||||
| 	} | ||||
| 	pfGenesis := pricefeed.GenesisState{ | ||||
| 		Params: ap, | ||||
| 		PostedPrices: []pricefeed.PostedPrice{ | ||||
| 			pricefeed.PostedPrice{ | ||||
| 				MarketID:      "btc", | ||||
| 				OracleAddress: sdk.AccAddress{}, | ||||
| 				Price:         sdk.MustNewDecFromStr("8000.00"), | ||||
| 				Expiry:        time.Unix(9999999999, 0), // some deterministic future date,
 | ||||
| 			}, | ||||
| 			pricefeed.PostedPrice{ | ||||
| 				MarketID:      "xrp", | ||||
| 				OracleAddress: sdk.AccAddress{}, | ||||
| 				Price:         sdk.MustNewDecFromStr("0.25"), | ||||
| 				Expiry:        time.Unix(9999999999, 0), // some deterministic future date,
 | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	return app.GenesisState{pricefeed.ModuleName: pricefeed.ModuleCdc.MustMarshalJSON(pfGenesis)} | ||||
| } | ||||
| func NewCDPGenStateMulti() app.GenesisState { | ||||
| 	cdpGenesis := cdp.GenesisState{ | ||||
| 		Params: cdp.CdpParams{ | ||||
| 			GlobalDebtLimit: sdk.NewInt(1000000), | ||||
| 			CollateralParams: []types.CollateralParams{ | ||||
| 				{ | ||||
| 					Denom:            "btc", | ||||
| 					LiquidationRatio: sdk.MustNewDecFromStr("1.5"), | ||||
| 					DebtLimit:        sdk.NewInt(500000), | ||||
| 				}, | ||||
| 				{ | ||||
| 					Denom:            "xrp", | ||||
| 					LiquidationRatio: sdk.MustNewDecFromStr("2.0"), | ||||
| 					DebtLimit:        sdk.NewInt(500000), | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 		GlobalDebt: sdk.ZeroInt(), | ||||
| 		CDPs:       cdp.CDPs{}, | ||||
| 	} | ||||
| 	return app.GenesisState{cdp.ModuleName: cdp.ModuleCdc.MustMarshalJSON(cdpGenesis)} | ||||
| } | ||||
|  | ||||
| @ -11,7 +11,6 @@ import ( | ||||
| 
 | ||||
| 	"github.com/kava-labs/kava/app" | ||||
| 	"github.com/kava-labs/kava/x/cdp/types" | ||||
| 	"github.com/kava-labs/kava/x/pricefeed" | ||||
| ) | ||||
| 
 | ||||
| // How could one reduce the number of params in the test cases. Create a table driven test for each of the 4 add/withdraw collateral/debt?
 | ||||
| @ -94,41 +93,19 @@ func TestKeeper_ModifyCDP(t *testing.T) { | ||||
| 	} | ||||
| 	for _, tc := range tests { | ||||
| 		t.Run(tc.name, func(t *testing.T) { | ||||
| 			// setup keeper
 | ||||
| 			// setup test app
 | ||||
| 			tApp := app.NewTestApp() | ||||
| 			// initialize cdp owner account with coins
 | ||||
| 			authGen := app.NewAuthGenState([]sdk.AccAddress{ownerAddr}, []sdk.Coins{tc.priorState.OwnerCoins}) | ||||
| 			tApp.InitializeFromGenesisStates(authGen) | ||||
| 			// initialize cdp owner account with coins, and collateral with price and params
 | ||||
| 			tApp.InitializeFromGenesisStates( | ||||
| 				app.NewAuthGenState([]sdk.AccAddress{ownerAddr}, []sdk.Coins{tc.priorState.OwnerCoins}), | ||||
| 				NewPFGenState("xrp", d(tc.price)), | ||||
| 				NewCDPGenState("xrp", d("2.0")), | ||||
| 			) | ||||
| 			// create a context for db access
 | ||||
| 			ctx := tApp.NewContext(false, abci.Header{}) | ||||
| 
 | ||||
| 			// setup store state
 | ||||
| 			keeper := tApp.GetCDPKeeper() | ||||
| 			keeper.SetParams(ctx, defaultParamsSingle()) | ||||
| 			pricefeedKeeper := tApp.GetPriceFeedKeeper() | ||||
| 			ap := pricefeed.Params{ | ||||
| 				Markets: []pricefeed.Market{ | ||||
| 					pricefeed.Market{ | ||||
| 						MarketID: "xrp", BaseAsset: "xrp", | ||||
| 						QuoteAsset: "usd", Oracles: pricefeed.Oracles{}, Active: true}, | ||||
| 				}, | ||||
| 			} | ||||
| 			pricefeedKeeper.SetParams(ctx, ap) | ||||
| 			_, err := pricefeedKeeper.SetPrice( | ||||
| 				ctx, ownerAddr, "xrp", | ||||
| 				sdk.MustNewDecFromStr(tc.price), | ||||
| 				time.Unix(9999999999, 0)) // some deterministic future date
 | ||||
| 			if err != nil { | ||||
| 				t.Log("test context height", ctx.BlockHeight()) | ||||
| 				t.Log(err) | ||||
| 				t.Log(tc.name) | ||||
| 			} | ||||
| 			err = pricefeedKeeper.SetCurrentPrices(ctx, "xrp") | ||||
| 			if err != nil { | ||||
| 				t.Log("test context height", ctx.BlockHeight()) | ||||
| 				t.Log(err) | ||||
| 				t.Log(tc.name) | ||||
| 			} | ||||
| 			if tc.priorState.CDP.CollateralDenom != "" { // check if the prior CDP should be created or not (see if an empty one was specified)
 | ||||
| 				keeper.SetCDP(ctx, tc.priorState.CDP) | ||||
| 			} | ||||
| @ -138,7 +115,7 @@ func TestKeeper_ModifyCDP(t *testing.T) { | ||||
| 			} | ||||
| 
 | ||||
| 			// call func under test
 | ||||
| 			err = keeper.ModifyCDP(ctx, tc.args.owner, tc.args.collateralDenom, tc.args.changeInCollateral, tc.args.changeInDebt) | ||||
| 			err := keeper.ModifyCDP(ctx, tc.args.owner, tc.args.collateralDenom, tc.args.changeInCollateral, tc.args.changeInDebt) | ||||
| 
 | ||||
| 			// get new state for verification
 | ||||
| 			actualCDP, found := keeper.GetCDP(ctx, tc.args.owner, tc.args.collateralDenom) | ||||
| @ -172,38 +149,23 @@ func TestKeeper_PartialSeizeCDP(t *testing.T) { | ||||
| 	testAddr := addrs[0] | ||||
| 
 | ||||
| 	tApp := app.NewTestApp() | ||||
| 	authGenState := app.NewAuthGenState(addrs, []sdk.Coins{cs(c(collateral, 100))}) | ||||
| 	tApp.InitializeFromGenesisStates(authGenState) | ||||
| 	tApp.InitializeFromGenesisStates( | ||||
| 		app.NewAuthGenState(addrs, []sdk.Coins{cs(c(collateral, 100))}), | ||||
| 		NewPFGenState(collateral, d("1.00")), | ||||
| 		NewCDPGenState(collateral, d("2.00")), | ||||
| 	) | ||||
| 
 | ||||
| 	ctx := tApp.NewContext(false, abci.Header{}) | ||||
| 	keeper := tApp.GetCDPKeeper() | ||||
| 
 | ||||
| 	// setup pricefeed
 | ||||
| 	pricefeedKeeper := tApp.GetPriceFeedKeeper() | ||||
| 	ap := pricefeed.Params{ | ||||
| 		Markets: []pricefeed.Market{ | ||||
| 			pricefeed.Market{ | ||||
| 				MarketID: "xrp", BaseAsset: collateral, | ||||
| 				QuoteAsset: "usd", Oracles: pricefeed.Oracles{}, Active: true}, | ||||
| 		}, | ||||
| 	} | ||||
| 	pricefeedKeeper.SetParams(ctx, ap) | ||||
| 	pricefeedKeeper.SetPrice( | ||||
| 		ctx, sdk.AccAddress{}, collateral, | ||||
| 		sdk.MustNewDecFromStr("1.00"), | ||||
| 		time.Unix(9999999999, 0)) // some deterministic future date
 | ||||
| 	pricefeedKeeper.SetCurrentPrices(ctx, collateral) | ||||
| 
 | ||||
| 	// Create CDP
 | ||||
| 	keeper.SetParams(ctx, defaultParamsSingle()) | ||||
| 	err := keeper.ModifyCDP(ctx, testAddr, collateral, i(10), i(5)) | ||||
| 	require.NoError(t, err) | ||||
| 	// Reduce price
 | ||||
| 	pricefeedKeeper.SetPrice( | ||||
| 	tApp.GetPriceFeedKeeper().SetPrice( | ||||
| 		ctx, sdk.AccAddress{}, collateral, | ||||
| 		sdk.MustNewDecFromStr("0.90"), | ||||
| 		time.Unix(9999999999, 0)) // some deterministic future date
 | ||||
| 	pricefeedKeeper.SetCurrentPrices(ctx, collateral) | ||||
| 		d("0.90"), time.Unix(9999999999, 0)) // some deterministic future date
 | ||||
| 	tApp.GetPriceFeedKeeper().SetCurrentPrices(ctx, collateral) | ||||
| 
 | ||||
| 	// Seize entire CDP
 | ||||
| 	err = keeper.PartialSeizeCDP(ctx, testAddr, collateral, i(10), i(5)) | ||||
| @ -218,11 +180,14 @@ func TestKeeper_PartialSeizeCDP(t *testing.T) { | ||||
| } | ||||
| 
 | ||||
| func TestKeeper_GetCDPs(t *testing.T) { | ||||
| 	// setup keeper
 | ||||
| 	tApp := app.NewTestApp() | ||||
| 	// setup test app
 | ||||
| 	tApp := app.NewTestApp().InitializeFromGenesisStates( | ||||
| 		NewPFGenStateMulti(), // collateral needs to be in pricefeed for cdp InitGenesis to validate
 | ||||
| 		NewCDPGenStateMulti(), | ||||
| 	) | ||||
| 	ctx := tApp.NewContext(true, abci.Header{}) | ||||
| 	keeper := tApp.GetCDPKeeper() | ||||
| 	keeper.SetParams(ctx, defaultParamsMulti()) | ||||
| 
 | ||||
| 	// setup CDPs
 | ||||
| 	_, addrs := app.GeneratePrivKeyAddressPairs(2) | ||||
| 	cdps := types.CDPs{ | ||||
| @ -299,7 +264,6 @@ func TestKeeper_GetSetDeleteCDP(t *testing.T) { | ||||
| 	ctx := tApp.NewContext(true, abci.Header{}) | ||||
| 	keeper := tApp.GetCDPKeeper() | ||||
| 
 | ||||
| 	keeper.SetParams(ctx, defaultParamsSingle()) | ||||
| 	_, addrs := app.GeneratePrivKeyAddressPairs(1) | ||||
| 	cdp := types.CDP{addrs[0], "xrp", i(412), i(56)} | ||||
| 
 | ||||
| @ -323,7 +287,7 @@ func TestKeeper_GetSetGDebt(t *testing.T) { | ||||
| 	tApp := app.NewTestApp() | ||||
| 	ctx := tApp.NewContext(true, abci.Header{}) | ||||
| 	keeper := tApp.GetCDPKeeper() | ||||
| 	keeper.SetParams(ctx, defaultParamsSingle()) | ||||
| 
 | ||||
| 	gDebt := i(4120000) | ||||
| 
 | ||||
| 	// write and read from store
 | ||||
| @ -339,7 +303,7 @@ func TestKeeper_GetSetCollateralState(t *testing.T) { | ||||
| 	tApp := app.NewTestApp() | ||||
| 	ctx := tApp.NewContext(true, abci.Header{}) | ||||
| 	keeper := tApp.GetCDPKeeper() | ||||
| 	keeper.SetParams(ctx, defaultParamsSingle()) | ||||
| 
 | ||||
| 	collateralState := types.CollateralState{"xrp", i(15400)} | ||||
| 
 | ||||
| 	// write and read from store
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 rhuairahrighairigh
						rhuairahrighairigh