diff --git a/app/test_helpers.go b/app/test_helpers.go new file mode 100644 index 000000000..bcfd14125 --- /dev/null +++ b/app/test_helpers.go @@ -0,0 +1,78 @@ +package app + +import ( + "encoding/json" + "github.com/cosmos/cosmos-sdk/simapp" + simappparams "github.com/cosmos/cosmos-sdk/simapp/params" + "github.com/cosmos/cosmos-sdk/std" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + tmtypes "github.com/tendermint/tendermint/types" + dbm "github.com/tendermint/tm-db" + "time" +) + +// DefaultConsensusParams defines the default Tendermint consensus params used in +// App testing. +var DefaultConsensusParams = &abci.ConsensusParams{ + Block: &abci.BlockParams{ + MaxBytes: 200000, + MaxGas: 2000000, + }, + Evidence: &tmproto.EvidenceParams{ + MaxAgeNumBlocks: 302400, + MaxAgeDuration: 504 * time.Hour, // 3 weeks is the max duration + MaxBytes: 10000, + }, + Validator: &tmproto.ValidatorParams{ + PubKeyTypes: []string{ + tmtypes.ABCIPubKeyTypeEd25519, + }, + }, +} + +func MakeTestEncodingConfig() simappparams.EncodingConfig { + encodingConfig := simappparams.MakeTestEncodingConfig() + std.RegisterLegacyAminoCodec(encodingConfig.Amino) + std.RegisterInterfaces(encodingConfig.InterfaceRegistry) + ModuleBasics.RegisterLegacyAminoCodec(encodingConfig.Amino) + ModuleBasics.RegisterInterfaces(encodingConfig.InterfaceRegistry) + return encodingConfig +} + +func setup(withGenesis bool, invCheckPeriod uint) (*App, GenesisState) { + db := dbm.NewMemDB() + encCdc := MakeTestEncodingConfig() + app := New(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, invCheckPeriod, MakeEncodingConfig(), simapp.EmptyAppOptions{}, GetWasmEnabledProposals(), EmptyWasmOpts) + if withGenesis { + return app, NewDefaultGenesisState(encCdc.Marshaler) + } + return app, GenesisState{} +} + +// Setup initializes a new App. A Nop logger is set in App. +func Setup(isCheckTx bool) *App { + app, genesisState := setup(!isCheckTx, 5) + if !isCheckTx { + // init chain must be called to stop deliverState from being nil + stateBytes, err := json.MarshalIndent(genesisState, "", " ") + if err != nil { + panic(err) + } + + // Initialize the chain + app.InitChain( + abci.RequestInitChain{ + Validators: []abci.ValidatorUpdate{}, + ConsensusParams: DefaultConsensusParams, + AppStateBytes: stateBytes, + }, + ) + } + + return app +} + +// EmptyAppOptions is a stub implementing AppOptions +type EmptyAppOptions struct{} diff --git a/x/auction/keeper/debt.go b/x/auction/keeper/debt.go index cda9e450e..59bd0d01c 100644 --- a/x/auction/keeper/debt.go +++ b/x/auction/keeper/debt.go @@ -83,7 +83,7 @@ func (k Keeper) checkStatusOfNetFeesCollectedAndStartDebtAuction(ctx sdk.Context } //Mint the tokens when collector module sends tokens to user - err := k.startDebtAuction(ctx, outflowToken, inflowToken, collector.BidFactor, appID, assetID, assetInID, assetOutID) + err := k.StartDebtAuction(ctx, outflowToken, inflowToken, collector.BidFactor, appID, assetID, assetInID, assetOutID) if err != nil { break } @@ -116,7 +116,7 @@ func (k Keeper) getDebtSellTokenAmount(ctx sdk.Context, appID, AssetInID, AssetO return 5, sellToken, buyToken } -func (k Keeper) startDebtAuction( +func (k Keeper) StartDebtAuction( ctx sdk.Context, auctionToken sdk.Coin, //sell token expectedUserToken sdk.Coin, // buy token diff --git a/x/auction/keeper/debt_test.go b/x/auction/keeper/debt_test.go new file mode 100644 index 000000000..dda58d898 --- /dev/null +++ b/x/auction/keeper/debt_test.go @@ -0,0 +1,197 @@ +package keeper_test + +import ( + "fmt" + + "github.com/comdex-official/comdex/x/auction/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const advanceSeconds = 21601 + +func (s *KeeperTestSuite) PrintDebtAuction(auction types.DebtAuction) { + fmt.Println("") + fmt.Println("printing debt auction : ") + fmt.Println(auction.AuctionId) + fmt.Println(auction.AppId) + fmt.Println(auction.AssetId) + fmt.Println(auction.AuctionedToken) + fmt.Println(auction.ExpectedUserToken) + fmt.Println(auction.ExpectedMintedToken) + fmt.Println(auction.Bidder) + fmt.Println(auction.ActiveBiddingId) + fmt.Println(auction.EndTime) + fmt.Println(auction.AuctionStatus) + fmt.Println(auction.CurrentBidAmount) + fmt.Println(auction.BiddingIds) + fmt.Println("") +} + +func (s *KeeperTestSuite) PrintDebtBid(bid types.DebtBiddings) { + fmt.Println("printing debt bid : ") + fmt.Println(bid.BiddingId) + fmt.Println(bid.AuctionId) + fmt.Println(bid.AuctionStatus) + fmt.Println(bid.OutflowTokens) + fmt.Println(bid.Bidder) + fmt.Println(bid.Bid) + fmt.Println(bid.BiddingTimestamp) + fmt.Println(bid.BiddingStatus) + +} + +func (s *KeeperTestSuite) TestCreateDebtAuction() { + bidFactor := sdk.MustNewDecFromStr("0.01") + assetInId := uint64(1) + assetOutId := uint64(2) + k, ctx := &s.keeper, &s.ctx + auctionMapppingId := uint64(2) + outflowToken := ParseCoin("250denom1") + err := s.app.BankKeeper.MintCoins(s.ctx, types.ModuleName, sdk.NewCoins(outflowToken)) + s.Require().NoError(err) + + inflowToken := ParseCoin("100denom2") + appId := uint64(1) + assetId := uint64(2) + + //start auction + err = k.StartDebtAuction(*ctx, outflowToken, inflowToken, bidFactor, appId, assetId, assetInId, assetOutId) + s.Require().NoError(err) + + auction, err := k.GetDebtAuction(*ctx, appId, auctionMapppingId, 1) + s.Require().NoError(err) + s.PrintDebtAuction(auction) + s.Require().Equal(uint64(1), auction.AuctionId) +} + +func (s *KeeperTestSuite) TestBidDebtAuction() { + k, ctx := &s.keeper, &s.ctx + appId := uint64(1) + auctionMappingId := uint64(2) + auctionId := uint64(1) + //create auction + s.TestCreateDebtAuction() + user_tokens := ParseCoin("1000denom2") + + expectedUserToken := ParseCoin("100denom2") + bid := ParseCoin("245denom1") + bidder, err := sdk.AccAddressFromBech32("cosmos155hjlwufdfu4c3hycylzz74ag9anz7lkfurxwg") + s.Require().NoError(err) + + //fund bidder + s.fundAddr(bidder, sdk.NewCoins(user_tokens)) + + //place bid + err = k.PlaceDebtAuctionBid(*ctx, appId, auctionMappingId, auctionId, bidder, bid, expectedUserToken) + s.Require().NoError(err) + + auction, err := k.GetDebtAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) + s.Require().Equal(auction.ActiveBiddingId, uint64(1)) + //check if user balance reduced + s.Require().Equal(sdk.NewInt(900), k.GetBalance(*ctx, bidder, "denom2").Amount) + s.Require().Equal(bidder, auction.Bidder) + s.PrintDebtAuction(auction) + + bidding, err := k.GetDebtUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDebtBid(bidding) + + //close auction by advancing time + s.advanceseconds(advanceSeconds) + err = k.DebtAuctionClose(*ctx, appId) + s.Require().NoError(err) + fmt.Println(k.GetBalance(*ctx, bidder, "denom1").Amount) + //check if user got collateral + s.Require().Equal(sdk.NewInt(250), k.GetBalance(*ctx, bidder, "denom1").Amount) + + //check status of bid + bidding, err = k.GetHistoryDebtUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDebtBid(bidding) + + //get closed auction + _, err = k.GetHistoryDebtAuction(*ctx, appId, auctionMappingId, 1) + s.Require().NoError(err) +} + +func (s *KeeperTestSuite) TestBidsDebtAuction() { + k, ctx := &s.keeper, &s.ctx + appId := uint64(1) + auctionMappingId := uint64(2) + auctionId := uint64(1) + //create auction + s.TestCreateDebtAuction() + user_tokens := ParseCoin("1000denom2") + + expectedUserToken := ParseCoin("100denom2") + + //bid1 + bid := ParseCoin("240denom1") + bidder, err := sdk.AccAddressFromBech32("cosmos155hjlwufdfu4c3hycylzz74ag9anz7lkfurxwg") + s.Require().NoError(err) + + //fund bidder + s.fundAddr(bidder, sdk.NewCoins(user_tokens)) + + //place bid1 + err = k.PlaceDebtAuctionBid(*ctx, appId, auctionMappingId, auctionId, bidder, bid, expectedUserToken) + s.Require().NoError(err) + auction, err := k.GetDebtAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) + s.Require().Equal(auction.ActiveBiddingId, uint64(1)) + //check if user balance reduced + s.Require().Equal(sdk.NewInt(900), k.GetBalance(*ctx, bidder, "denom2").Amount) + s.Require().Equal(bidder, auction.Bidder) + s.PrintDebtAuction(auction) + bidding, err := k.GetDebtUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDebtBid(bidding) + + //bid2 + bidder2, err := sdk.AccAddressFromBech32("cosmos1q7q90qsl9g0gl2zz0njxwv2a649yqrtyxtnv3v") + s.Require().NoError(err) + + //fund bidder2 + s.fundAddr(bidder2, sdk.NewCoins(user_tokens)) + bid = ParseCoin("235denom1") + + //place bid + err = k.PlaceDebtAuctionBid(*ctx, appId, auctionMappingId, auctionId, bidder2, bid, expectedUserToken) + fmt.Println(err) + s.Require().NoError(err) + //place bid2 + auction, err = k.GetDebtAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) + s.Require().Equal(auction.ActiveBiddingId, uint64(2)) + s.PrintDebtAuction(auction) + s.Require().Equal(sdk.NewInt(900), k.GetBalance(*ctx, bidder2, "denom2").Amount) + s.Require().Equal(sdk.NewInt(1000), k.GetBalance(*ctx, bidder, "denom2").Amount) + + //close auction by advancing time + s.advanceseconds(advanceSeconds) + err = k.DebtAuctionClose(*ctx, appId) + s.Require().NoError(err) + fmt.Println(k.GetBalance(*ctx, bidder2, "denom1").Amount) + //check if user got collateral + s.Require().Equal(sdk.NewInt(243), k.GetBalance(*ctx, bidder2, "denom1").Amount) + + //check status of bid + bidding, err = k.GetHistoryDebtUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDebtBid(bidding) + + //get closed auction + _, err = k.GetHistoryDebtAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) +} + +/* 1. auction closed but no bids then auction should restart +2. make sure code enter every if condition or every part of code +3. make sure to change numbers +4.test maths this where quo involved with smaller numbers and also places sdk.Int involved in quo +5.check chost block entered +6.advance time in dutch test so that collateral gets over but target cmst is still left +7.make fetch price dynamic in dutch as of now linear is hard coded +8.handle if auctiontype is empty in setters +// */ diff --git a/x/auction/keeper/dutch_test.go b/x/auction/keeper/dutch_test.go new file mode 100644 index 000000000..8cb773a6a --- /dev/null +++ b/x/auction/keeper/dutch_test.go @@ -0,0 +1,219 @@ +package keeper_test + +import ( + "fmt" + "github.com/comdex-official/comdex/x/auction/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *KeeperTestSuite) PrintDutchAuction(auction types.DutchAuction) { + fmt.Println("") + fmt.Println("printing dutch auction : ") + fmt.Println(auction.AuctionId) + fmt.Println(auction.OutflowTokenInitAmount) + fmt.Println(auction.OutflowTokenCurrentAmount) + fmt.Println(auction.InflowTokenTargetAmount) + fmt.Println(auction.InflowTokenCurrentAmount) // make it 0 + fmt.Println(auction.OutflowTokenInitialPrice) + fmt.Println(auction.OutflowTokenCurrentPrice) + fmt.Println(auction.OutflowTokenEndPrice) + fmt.Println(auction.InflowTokenCurrentPrice) + fmt.Println(auction.EndTime) + fmt.Println(auction.AuctionStatus) + fmt.Println(auction.StartTime) + fmt.Println(auction.BiddingIds) + fmt.Println(auction.AuctionMappingId) + fmt.Println(auction.AppId) + fmt.Println(auction.AssetInId) + fmt.Println(auction.AssetOutId) + fmt.Println(auction.LockedVaultId) + fmt.Println(auction.VaultOwner) + fmt.Println(auction.LiquidationPenalty) + + fmt.Println("") +} + +func (s *KeeperTestSuite) PrintDutchBid(bid types.DutchBiddings) { + fmt.Println("printing dutch bid : ") + fmt.Println(bid.BiddingId) + fmt.Println(bid.AuctionId) + fmt.Println(bid.AuctionStatus) + fmt.Println(bid.OutflowTokenAmount) + fmt.Println(bid.InflowTokenAmount) + fmt.Println(bid.Bidder) + fmt.Println(bid.BiddingTimestamp) + fmt.Println(bid.BiddingStatus) + fmt.Println(bid.AuctionMappingId) + fmt.Println(bid.AppId) +} + +func (s *KeeperTestSuite) TestCreateDutchAuction() { + k, ctx := &s.keeper, &s.ctx + outflowToken := ParseCoin("250denom1") + err := s.app.BankKeeper.MintCoins(s.ctx, types.ModuleName, sdk.NewCoins(outflowToken)) + s.Require().NoError(err) + + dutchId := uint64(3) + inflowToken := ParseCoin("100denom2") + appId := uint64(1) + assetInId := uint64(2) + assetOutId := uint64(3) + //outFlowTokenAddress, err := sdk.AccAddressFromBech32("cosmos1944ddjhecz5hfm8yp2496zu9u45vl5s7qc7vdc") + //s.Require().NoError(err) + //inFlowTokenAddress, err := sdk.AccAddressFromBech32("cosmos1hfml4tzwlc3mvynsg6vtgywyx00wfkhrtpkx6t") + //s.Require().NoError(err) + lockedVaultOwner, err := sdk.AccAddressFromBech32("cosmos1hfml4tzwlc3mvynsg6vtgywyx00wfkhrtpkx6t") + s.Require().NoError(err) + liquidationPenalty := sdk.MustNewDecFromStr("0.15") + lockedVaultId := uint64(1) + //start auction + err = k.StartDutchAuction(*ctx, outflowToken, inflowToken, appId, assetInId, assetOutId, lockedVaultId, lockedVaultOwner.String(), liquidationPenalty) + s.Require().NoError(err) + + auction, err := k.GetDutchAuction(*ctx, appId, dutchId, 1) + s.Require().NoError(err) + s.PrintDutchAuction(auction) + s.Require().Equal(uint64(1), auction.AuctionId) + err = k.DeleteDutchAuction(*ctx, auction) + s.Require().NoError(err) + d := k.GetDutchAuctions(*ctx, 1) + fmt.Println(d) +} + +func getPriceFromLinearDecreaseFunction(top sdk.Dec, tau, dur sdk.Int) sdk.Int { + result1 := tau.Sub(dur) + result2 := top.MulInt(result1) + result3 := result2.Quo(tau.ToDec()) + return result3.TruncateInt() +} +func (s *KeeperTestSuite) TestLinearPriceFunction() { + top := sdk.MustNewDecFromStr("100").Mul(sdk.MustNewDecFromStr("1")) + tau := sdk.NewIntFromUint64(60) + dur := sdk.NewInt(0) + for n := 0; n <= 60; n++ { + fmt.Println("top tau dur seconds") + fmt.Println(top, tau, dur) + fmt.Println("price") + price := getPriceFromLinearDecreaseFunction(top, tau, dur) + fmt.Println(price) + dur = dur.Add(sdk.NewInt(1)) + + } +} + +func (s *KeeperTestSuite) TestBidDutchAuction() { + k, ctx := &s.keeper, &s.ctx + appId := uint64(1) + auctionMappingId := uint64(3) + auctionId := uint64(1) + max := sdk.MustNewDecFromStr("12") + //create auction + s.TestCreateDutchAuction() + userTokens := ParseCoin("2500denom2") + + bid := ParseCoin("5denom1") + bidder, err := sdk.AccAddressFromBech32("cosmos155hjlwufdfu4c3hycylzz74ag9anz7lkfurxwg") + s.Require().NoError(err) + + //fund bidder + s.fundAddr(bidder, sdk.NewCoins(userTokens)) + + //place bid + err = k.PlaceDutchAuctionBid(*ctx, appId, auctionMappingId, auctionId, bidder, bid, max) + s.Require().NoError(err) + auction, err := k.GetDutchAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) + //check if user balance reduced + fmt.Println(k.GetBalance(*ctx, bidder, "denom2")) + //s.Require().Equal(sdk.NewInt(880), k.GetBalance(*ctx, bidder, "denom2").Amount) + s.PrintDutchAuction(auction) + bidding, err := k.GetDutchUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDutchBid(bidding) + + //close auction by advancing time + //s.advanceseconds(advanceSeconds) + //k.CloseDutchAuction(*ctx, auction) + + fmt.Println(k.GetBalance(*ctx, bidder, "denom1")) + fmt.Println(k.GetBalance(*ctx, bidder, "denom2")) + //check if user got collateral + s.Require().Equal(sdk.NewInt(10), k.GetBalance(*ctx, bidder, "denom1").Amount) + + //check status of bid + bidding, err = k.GetHistoryDutchUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDutchBid(bidding) + + //get closed auction + _, err = k.GetHistoryDutchAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) +} + +func (s *KeeperTestSuite) TestBidsDutchAuction() { + k, ctx := &s.keeper, &s.ctx + appId := uint64(1) + auctionMappingId := uint64(3) + auctionId := uint64(1) + max := sdk.MustNewDecFromStr("12") + //create auction + s.TestCreateDutchAuction() + userTokens := ParseCoin("1000denom2") + + bid := ParseCoin("10denom1") + bidder, err := sdk.AccAddressFromBech32("cosmos155hjlwufdfu4c3hycylzz74ag9anz7lkfurxwg") + s.Require().NoError(err) + + //fund bidder + s.fundAddr(bidder, sdk.NewCoins(userTokens)) + + //place bid + err = k.PlaceDutchAuctionBid(*ctx, appId, auctionMappingId, auctionId, bidder, bid, max) + s.Require().NoError(err) + auction, err := k.GetDutchAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) + //check if user balance reduced + fmt.Println(k.GetBalance(*ctx, bidder, "denom2")) + //s.Require().Equal(sdk.NewInt(880), k.GetBalance(*ctx, bidder, "denom2").Amount) + s.PrintDutchAuction(auction) + bidding, err := k.GetDutchUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDutchBid(bidding) + + //place bid + err = k.PlaceDutchAuctionBid(*ctx, appId, auctionMappingId, auctionId, bidder, bid, max) + s.Require().NoError(err) + auction, err = k.GetDutchAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) + //check if user balance reduced + fmt.Println(k.GetBalance(*ctx, bidder, "denom2")) + //s.Require().Equal(sdk.NewInt(880), k.GetBalance(*ctx, bidder, "denom2").Amount) + s.PrintDutchAuction(auction) + bidding, err = k.GetDutchUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDutchBid(bidding) + //close auction by advancing time + s.advanceseconds(advanceSeconds) + k.CloseDutchAuction(*ctx, auction) + + fmt.Println(k.GetBalance(*ctx, bidder, "denom1")) + //check if user got collateral + s.Require().Equal(sdk.NewInt(10), k.GetBalance(*ctx, bidder, "denom1").Amount) + + //check status of bid + bidding, err = k.GetHistoryDutchUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintDutchBid(bidding) + + //get closed auction + _, err = k.GetHistoryDutchAuction(*ctx, appId, auctionMappingId, auctionId) + s.Require().NoError(err) +} + +func (s *KeeperTestSuite) Test() { + _, ctx := &s.keeper, &s.ctx + time1 := ctx.BlockTime() + s.advanceseconds(2933222) + fmt.Println("red") + fmt.Println(ctx.BlockTime().Sub(time1).Seconds()) +} diff --git a/x/auction/keeper/keeper_test.go b/x/auction/keeper/keeper_test.go index cc0254432..988e5046e 100644 --- a/x/auction/keeper/keeper_test.go +++ b/x/auction/keeper/keeper_test.go @@ -1,41 +1,42 @@ package keeper_test -// -//import ( -// "encoding/binary" +import ( + "fmt" + "time" + + "github.com/stretchr/testify/suite" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + chain "github.com/comdex-official/comdex/app" + "github.com/comdex-official/comdex/x/auction/keeper" + "github.com/comdex-official/comdex/x/auction/types" +) + +type KeeperTestSuite struct { + suite.Suite + + app *chain.App + ctx sdk.Context + keeper keeper.Keeper + querier keeper.QueryServer + msgServer types.MsgServer +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (s *KeeperTestSuite) SetupTest() { + s.app = chain.Setup(false) + s.ctx = s.app.BaseApp.NewContext(false, tmproto.Header{}) + s.keeper = s.app.AuctionKeeper + s.querier = keeper.QueryServer{Keeper: s.keeper} + s.msgServer = keeper.NewMsgServiceServer(s.keeper) +} -// "github.com/stretchr/testify/suite" -// "testing" -// -// sdk "github.com/cosmos/cosmos-sdk/types" -// tmproto "github.com/tendermint/tendermint/proto/tendermint/types" -// -// chain "github.com/comdex-official/comdex/app" -// "github.com/comdex-official/comdex/x/auction/keeper" -// "github.com/comdex-official/comdex/x/auction/types" -//) -// -//type KeeperTestSuite struct { -// suite.Suite -// -// app *chain.App -// ctx sdk.Context -// keeper keeper.Keeper -// querier keeper.queryServer -// msgServer types.MsgServiceServer -//} -// -//func TestKeeperTestSuite(t *testing.T) { -// suite.Run(t, new(KeeperTestSuite)) -//} -// -//func (s *KeeperTestSuite) SetupTest() { -// s.app = chain.Setup(false) -// s.ctx = s.app.BaseApp.NewContext(false, tmproto.Header{}) -// s.keeper = s.app.a -// s.querier = keeper.Querier{Keeper: s.keeper} -// s.msgServer = keeper.NewMsgServerImpl(s.keeper) -//} // //// Below are just shortcuts to frequently-used functions. //func (s *KeeperTestSuite) getBalances(addr sdk.AccAddress) sdk.Coins { @@ -63,11 +64,25 @@ package keeper_test // binary.PutVarint(addr, int64(addrNum)) // return addr //} -// -//func (s *KeeperTestSuite) fundAddr(addr sdk.AccAddress, amt sdk.Coins) { -// s.T().Helper() -// err := s.app.bankKeeper.MintCoins(s.ctx, types.ModuleName, amt) -// s.Require().NoError(err) -// err = s.app.bankKeeper.SendCoinsFromModuleToAccount(s.ctx, types.ModuleName, addr, amt) -// s.Require().NoError(err) -//} + +func (s *KeeperTestSuite) fundAddr(addr sdk.AccAddress, amt sdk.Coins) { + s.T().Helper() + err := s.app.BankKeeper.MintCoins(s.ctx, types.ModuleName, amt) + s.Require().NoError(err) + err = s.app.BankKeeper.SendCoinsFromModuleToAccount(s.ctx, types.ModuleName, addr, amt) + s.Require().NoError(err) +} + +func (s *KeeperTestSuite) advanceseconds(dur int64) { + s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(time.Second * time.Duration(dur))) + fmt.Println(s.ctx.BlockTime()) +} + +// ParseCoins parses and returns sdk.Coins. +func ParseCoin(s string) sdk.Coin { + coins, err := sdk.ParseCoinNormalized(s) + if err != nil { + panic(err) + } + return coins +} diff --git a/x/auction/keeper/surplus.go b/x/auction/keeper/surplus.go index 24ab02eb8..f499d10a6 100644 --- a/x/auction/keeper/surplus.go +++ b/x/auction/keeper/surplus.go @@ -93,7 +93,7 @@ func (k Keeper) checkStatusOfNetFeesCollectedAndStartSurplusAuction(ctx sdk.Cont return status, err } - err = k.startSurplusAuction(ctx, sellToken, buyToken, collector.BidFactor, appID, assetID, assetBuyID, assetSellID) + err = k.StartSurplusAuction(ctx, sellToken, buyToken, collector.BidFactor, appID, assetID, assetBuyID, assetSellID) if err != nil { return status, err } @@ -120,7 +120,7 @@ func (k Keeper) getSurplusBuyTokenAmount(ctx sdk.Context, AssetBuyID, AssetSellI return 5, sellToken, buyToken } -func (k Keeper) startSurplusAuction( +func (k Keeper) StartSurplusAuction( ctx sdk.Context, sellToken sdk.Coin, buyToken sdk.Coin, diff --git a/x/auction/keeper/surplus_test.go b/x/auction/keeper/surplus_test.go new file mode 100644 index 000000000..ee8ec2034 --- /dev/null +++ b/x/auction/keeper/surplus_test.go @@ -0,0 +1,163 @@ +package keeper_test + +import ( + "fmt" + "github.com/comdex-official/comdex/x/auction/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *KeeperTestSuite) PrintAuction(auction types.SurplusAuction) { + fmt.Println("printing surplus auction : ") + fmt.Println(auction.AuctionId) + fmt.Println(auction.AppId) + fmt.Println(auction.AssetId) + fmt.Println(auction.BuyToken) + fmt.Println(auction.SellToken) + fmt.Println(auction.Bidder) + fmt.Println(auction.Bid) + fmt.Println(auction.ActiveBiddingId) + fmt.Println(auction.EndTime) + fmt.Println(auction.BidFactor) + fmt.Println(auction.BiddingIds) + fmt.Println(auction.AuctionStatus) +} +func (s *KeeperTestSuite) PrintSurplusBid(bid types.SurplusBiddings) { + fmt.Println("printing surplus bid : ") + fmt.Println(bid.BiddingId) + fmt.Println(bid.AuctionId) + fmt.Println(bid.AuctionStatus) + fmt.Println(bid.AuctionedCollateral) + fmt.Println(bid.Bidder) + fmt.Println(bid.Bid) + fmt.Println(bid.BiddingTimestamp) + fmt.Println(bid.BiddingStatus) + +} +func (s *KeeperTestSuite) TestCreateSurplusAuction() { + k, ctx := &s.keeper, &s.ctx + outflowToken := ParseCoin("10000denom1") + err := s.app.BankKeeper.MintCoins(s.ctx, types.ModuleName, sdk.NewCoins(outflowToken)) + s.Require().NoError(err) + + inflowToken := ParseCoin("100denom2") + bidFactor := sdk.MustNewDecFromStr("0.01") + appId := uint64(1) + assetId := uint64(2) + assetInId := uint64(1) + assetOutId := uint64(2) + err = k.StartSurplusAuction(*ctx, outflowToken, inflowToken, bidFactor, appId, assetId, assetInId, assetOutId) + s.Require().NoError(err) + auction, err := k.GetSurplusAuction(*ctx, appId, 1, 1) + fmt.Println(auction) + s.Require().NoError(err) + //s.PrintAuction(auction) + s.Require().Equal(uint64(1), auction.AuctionId) + +} + +func (s *KeeperTestSuite) TestBidSurplusAuction() { + k, ctx := &s.keeper, &s.ctx + appId := uint64(1) + //create auction + s.TestCreateSurplusAuction() + user_tokens := ParseCoin("1000denom2") + bid := ParseCoin("100denom2") + bidder, err := sdk.AccAddressFromBech32("cosmos155hjlwufdfu4c3hycylzz74ag9anz7lkfurxwg") + s.Require().NoError(err) + + //fund bidder + s.fundAddr(bidder, sdk.NewCoins(user_tokens)) + + //place bid + err = k.PlaceSurplusAuctionBid(*ctx, appId, 1, 1, bidder, bid) + s.Require().NoError(err) + auction, err := k.GetSurplusAuction(*ctx, appId, 1, 1) + s.Require().NoError(err) + s.Require().Equal(auction.ActiveBiddingId, uint64(1)) + s.Require().Equal(sdk.NewInt(900), k.GetBalance(*ctx, bidder, "denom2").Amount) + s.Require().Equal(bidder, auction.Bidder) + s.PrintAuction(auction) + bidding, err := k.GetSurplusUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintSurplusBid(bidding) + + //close auction by advancing time + s.advanceseconds(advanceSeconds) + err = k.SurplusAuctionClose(*ctx, appId) + s.Require().NoError(err) + + //check if user got collateral + s.Require().Equal(sdk.NewInt(10000), k.GetBalance(*ctx, bidder, "denom1").Amount) + + //check status of bid + bidding, err = k.GetSurplusUserBidding(*ctx, bidder.String(), appId, 1) + s.Require().NoError(err) + s.PrintSurplusBid(bidding) + //get closed auction + _, err = k.GetSurplusAuction(*ctx, appId, 1, 1) + s.Require().NoError(err) +} + +func (s *KeeperTestSuite) TestBidsSurplusAuction() { + k, ctx := &s.keeper, &s.ctx + appId := uint64(1) + surplusAuction := uint64(1) + s.TestCreateSurplusAuction() + user_tokens := ParseCoin("1000denom2") + fmt.Println("bid 1") + + //bid1 + bid := ParseCoin("100denom2") + bidder, err := sdk.AccAddressFromBech32("cosmos155hjlwufdfu4c3hycylzz74ag9anz7lkfurxwg") + s.Require().NoError(err) + s.fundAddr(bidder, sdk.NewCoins(user_tokens)) + //place bid1 + err = k.PlaceSurplusAuctionBid(*ctx, appId, surplusAuction, 1, bidder, bid) + fmt.Println(err) + s.Require().NoError(err) + auction, err := k.GetSurplusAuction(*ctx, appId, surplusAuction, 1) + s.Require().NoError(err) + s.Require().Equal(auction.ActiveBiddingId, uint64(1)) + //s.Require().Equal(sdk.NewInt(900), k.GetBalance(*ctx, bidder, "denom2").Amount) + s.PrintAuction(auction) + + //bid2 + bidder2, err := sdk.AccAddressFromBech32("cosmos1q7q90qsl9g0gl2zz0njxwv2a649yqrtyxtnv3v") + s.Require().NoError(err) + + //fund bidder2 + s.fundAddr(bidder2, sdk.NewCoins(user_tokens)) + fmt.Println("bid 2") + bid2 := ParseCoin("120denom2") + + //place bid + err = k.PlaceSurplusAuctionBid(*ctx, appId, surplusAuction, 1, bidder2, bid2) + fmt.Println(err) + s.Require().NoError(err) + //place bid2 + auction, err = k.GetSurplusAuction(*ctx, appId, surplusAuction, 1) + s.Require().NoError(err) + s.Require().Equal(auction.ActiveBiddingId, uint64(2)) + s.PrintAuction(auction) + fmt.Println(k.GetBalance(*ctx, bidder2, "denom2")) + s.Require().Equal(sdk.NewInt(880), k.GetBalance(*ctx, bidder2, "denom2").Amount) + s.Require().Equal(sdk.NewInt(1000), k.GetBalance(*ctx, bidder, "denom2").Amount) + + //close auction by advancing time + s.advanceseconds(61) + err = k.SurplusAuctionClose(*ctx, appId) + s.Require().NoError(err) + //check if user got collateral + s.Require().Equal(sdk.NewInt(10000), k.GetBalance(*ctx, bidder2, "denom1").Amount) + + //print bid1 and bid2 + //bidding, found1 := k.GetSurplusUserBidding(*ctx, bidder.String(), appId, 1) + //s.Require().True(found1) + //s.PrintSurplusBid(bidding) + //bidding2, found2 := k.GetSurplusUserBidding(*ctx, bidder2.String(), appId, 2) + //s.Require().True(found2) + //s.PrintSurplusBid(bidding2) + ////get closed auction + //_, found = k.GetSurplusAuction(*ctx, appId, 1, 1) + //s.Require().False(found) +} diff --git a/x/locker/keeper/grpc_query.go b/x/locker/keeper/grpc_query.go index a89a3e8d7..e98834f08 100644 --- a/x/locker/keeper/grpc_query.go +++ b/x/locker/keeper/grpc_query.go @@ -10,19 +10,19 @@ import ( "google.golang.org/grpc/status" ) -var _ types.QueryServer = (*queryServer)(nil) +var _ types.QueryServer = (*QueryServer)(nil) -type queryServer struct { +type QueryServer struct { Keeper } func NewQueryServer(k Keeper) types.QueryServer { - return &queryServer{ + return &QueryServer{ Keeper: k, } } -func (q *queryServer) QueryParams(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { +func (q *QueryServer) QueryParams(c context.Context, _ *types.QueryParamsRequest) (*types.QueryParamsResponse, error) { var ( ctx = sdk.UnwrapSDKContext(c) params = q.GetParams(ctx) @@ -33,7 +33,7 @@ func (q *queryServer) QueryParams(c context.Context, _ *types.QueryParamsRequest }, nil } -func (q *queryServer) QueryLockerInfo(c context.Context, req *types.QueryLockerInfoRequest) (*types.QueryLockerInfoResponse, error) { +func (q *QueryServer) QueryLockerInfo(c context.Context, req *types.QueryLockerInfoRequest) (*types.QueryLockerInfoResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -43,7 +43,7 @@ func (q *queryServer) QueryLockerInfo(c context.Context, req *types.QueryLockerI ) item, found := q.GetLocker(ctx, req.Id) if !found { - return nil, status.Errorf(codes.NotFound, "locker-info does not exist for id %d", req.Id) + return nil, status.Errorf(codes.NotFound, "locker-info does not exist for id %s", req.Id) } return &types.QueryLockerInfoResponse{ @@ -51,7 +51,7 @@ func (q *queryServer) QueryLockerInfo(c context.Context, req *types.QueryLockerI }, nil } -func (q *queryServer) QueryLockersByProductToAssetID(c context.Context, request *types.QueryLockersByProductToAssetIDRequest) (*types.QueryLockersByProductToAssetIDResponse, error) { +func (q *QueryServer) QueryLockersByProductToAssetID(c context.Context, request *types.QueryLockersByProductToAssetIDRequest) (*types.QueryLockersByProductToAssetIDResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -83,7 +83,7 @@ func (q *queryServer) QueryLockersByProductToAssetID(c context.Context, request }, nil } -func (q *queryServer) QueryLockerInfoByProductID(c context.Context, request *types.QueryLockerInfoByProductIDRequest) (*types.QueryLockerInfoByProductIDResponse, error) { +func (q *QueryServer) QueryLockerInfoByProductID(c context.Context, request *types.QueryLockerInfoByProductIDRequest) (*types.QueryLockerInfoByProductIDResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -114,7 +114,7 @@ func (q *queryServer) QueryLockerInfoByProductID(c context.Context, request *typ } -func (q *queryServer) QueryTotalDepositByProductAssetID(c context.Context, request *types.QueryTotalDepositByProductAssetIDRequest) (*types.QueryTotalDepositByProductAssetIDResponse, error) { +func (q *QueryServer) QueryTotalDepositByProductAssetID(c context.Context, request *types.QueryTotalDepositByProductAssetIDRequest) (*types.QueryTotalDepositByProductAssetIDResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -146,7 +146,7 @@ func (q *queryServer) QueryTotalDepositByProductAssetID(c context.Context, reque }, nil } -func (q *queryServer) QueryLockerByProductByOwner(c context.Context, +func (q *QueryServer) QueryLockerByProductByOwner(c context.Context, request *types.QueryLockerByProductByOwnerRequest) (*types.QueryLockerByProductByOwnerResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") @@ -182,7 +182,7 @@ func (q *queryServer) QueryLockerByProductByOwner(c context.Context, }, nil } -func (q *queryServer) QueryOwnerLockerByProductIDbyOwner(c context.Context, request *types.QueryOwnerLockerByProductIDbyOwnerRequest) (*types.QueryOwnerLockerByProductIDbyOwnerResponse, error) { +func (q *QueryServer) QueryOwnerLockerByProductIDbyOwner(c context.Context, request *types.QueryOwnerLockerByProductIDbyOwnerRequest) (*types.QueryOwnerLockerByProductIDbyOwnerResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -214,7 +214,7 @@ func (q *queryServer) QueryOwnerLockerByProductIDbyOwner(c context.Context, requ }, nil } -func (q *queryServer) QueryOwnerLockerOfAllProductByOwner(c context.Context, request *types.QueryOwnerLockerOfAllProductByOwnerRequest) (*types.QueryOwnerLockerOfAllProductByOwnerResponse, error) { +func (q *QueryServer) QueryOwnerLockerOfAllProductByOwner(c context.Context, request *types.QueryOwnerLockerOfAllProductByOwnerRequest) (*types.QueryOwnerLockerOfAllProductByOwnerResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -236,7 +236,7 @@ func (q *queryServer) QueryOwnerLockerOfAllProductByOwner(c context.Context, req }, nil } -func (q *queryServer) QueryOwnerTxDetailsLockerOfProductByOwnerByAsset(c context.Context, request *types.QueryOwnerTxDetailsLockerOfProductByOwnerByAssetRequest) (*types.QueryOwnerTxDetailsLockerOfProductByOwnerByAssetResponse, error) { +func (q *QueryServer) QueryOwnerTxDetailsLockerOfProductByOwnerByAsset(c context.Context, request *types.QueryOwnerTxDetailsLockerOfProductByOwnerByAssetRequest) (*types.QueryOwnerTxDetailsLockerOfProductByOwnerByAssetResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -262,7 +262,7 @@ func (q *queryServer) QueryOwnerTxDetailsLockerOfProductByOwnerByAsset(c context }, nil } -func (q *queryServer) QueryOwnerLockerByProductToAssetIDbyOwner(c context.Context, request *types.QueryOwnerLockerByProductToAssetIDbyOwnerRequest) (*types.QueryOwnerLockerByProductToAssetIDbyOwnerResponse, error) { +func (q *QueryServer) QueryOwnerLockerByProductToAssetIDbyOwner(c context.Context, request *types.QueryOwnerLockerByProductToAssetIDbyOwnerRequest) (*types.QueryOwnerLockerByProductToAssetIDbyOwnerResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -299,7 +299,7 @@ func (q *queryServer) QueryOwnerLockerByProductToAssetIDbyOwner(c context.Contex }, nil } -func (q *queryServer) QueryLockerCountByProductID(c context.Context, request *types.QueryLockerCountByProductIDRequest) (*types.QueryLockerCountByProductIDResponse, error) { +func (q *QueryServer) QueryLockerCountByProductID(c context.Context, request *types.QueryLockerCountByProductIDRequest) (*types.QueryLockerCountByProductIDResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -335,7 +335,7 @@ func (q *queryServer) QueryLockerCountByProductID(c context.Context, request *ty } -func (q *queryServer) QueryLockerCountByProductToAssetID(c context.Context, request *types.QueryLockerCountByProductToAssetIDRequest) (*types.QueryLockerCountByProductToAssetIDResponse, error) { +func (q *QueryServer) QueryLockerCountByProductToAssetID(c context.Context, request *types.QueryLockerCountByProductToAssetIDRequest) (*types.QueryLockerCountByProductToAssetIDResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -372,7 +372,7 @@ func (q *queryServer) QueryLockerCountByProductToAssetID(c context.Context, requ }, nil } -func (q *queryServer) QueryWhiteListedAssetIDsByProductID(c context.Context, request *types.QueryWhiteListedAssetIDsByProductIDRequest) (*types.QueryWhiteListedAssetIDsByProductIDResponse, error) { +func (q *QueryServer) QueryWhiteListedAssetIDsByProductID(c context.Context, request *types.QueryWhiteListedAssetIDsByProductIDRequest) (*types.QueryWhiteListedAssetIDsByProductIDResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -403,7 +403,7 @@ func (q *queryServer) QueryWhiteListedAssetIDsByProductID(c context.Context, req }, nil } -func (q *queryServer) QueryWhiteListedAssetByAllProduct(c context.Context, request *types.QueryWhiteListedAssetByAllProductRequest) (*types.QueryWhiteListedAssetByAllProductResponse, error) { +func (q *QueryServer) QueryWhiteListedAssetByAllProduct(c context.Context, request *types.QueryWhiteListedAssetByAllProductRequest) (*types.QueryWhiteListedAssetByAllProductResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -441,7 +441,7 @@ func (q *queryServer) QueryWhiteListedAssetByAllProduct(c context.Context, reque }, nil } -func (q *queryServer) QueryLockerLookupTableByApp(c context.Context, req *types.QueryLockerLookupTableByAppRequest) (*types.QueryLockerLookupTableByAppResponse, error) { +func (q *QueryServer) QueryLockerLookupTableByApp(c context.Context, req *types.QueryLockerLookupTableByAppRequest) (*types.QueryLockerLookupTableByAppResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -459,7 +459,7 @@ func (q *queryServer) QueryLockerLookupTableByApp(c context.Context, req *types. }, nil } -func (q *queryServer) QueryLockerLookupTableByAppAndAssetId(c context.Context, req *types.QueryLockerLookupTableByAppAndAssetIdRequest) (*types.QueryLockerLookupTableByAppAndAssetIdResponse, error) { +func (q *QueryServer) QueryLockerLookupTableByAppAndAssetId(c context.Context, req *types.QueryLockerLookupTableByAppAndAssetIdRequest) (*types.QueryLockerLookupTableByAppAndAssetIdResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -484,7 +484,7 @@ func (q *queryServer) QueryLockerLookupTableByAppAndAssetId(c context.Context, r }, nil } -func (q *queryServer) QueryLockerTotalDepositedByApp(c context.Context, req *types.QueryLockerTotalDepositedByAppRequest) (*types.QueryLockerTotalDepositedByAppResponse, error) { +func (q *QueryServer) QueryLockerTotalDepositedByApp(c context.Context, req *types.QueryLockerTotalDepositedByAppRequest) (*types.QueryLockerTotalDepositedByAppResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -510,7 +510,7 @@ func (q *queryServer) QueryLockerTotalDepositedByApp(c context.Context, req *typ }, nil } -func (q *queryServer) QueryState(c context.Context, req *types.QueryStateRequest) (*types.QueryStateResponse, error) { +func (q *QueryServer) QueryState(c context.Context, req *types.QueryStateRequest) (*types.QueryStateResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } @@ -522,7 +522,7 @@ func (q *queryServer) QueryState(c context.Context, req *types.QueryStateRequest }, nil } -func (q *queryServer) QueryLockerTotalRewardsByAssetAppWise(c context.Context, request *types.QueryLockerTotalRewardsByAssetAppWiseRequest) (*types.QueryLockerTotalRewardsByAssetAppWiseResponse, error) { +func (q *QueryServer) QueryLockerTotalRewardsByAssetAppWise(c context.Context, request *types.QueryLockerTotalRewardsByAssetAppWiseRequest) (*types.QueryLockerTotalRewardsByAssetAppWiseResponse, error) { if request == nil { return nil, status.Error(codes.InvalidArgument, "request cannot be empty") } diff --git a/x/locker/keeper/keeper_test.go b/x/locker/keeper/keeper_test.go new file mode 100644 index 000000000..d83e048b7 --- /dev/null +++ b/x/locker/keeper/keeper_test.go @@ -0,0 +1,92 @@ +package keeper_test + +import ( + "fmt" + "time" + + "github.com/stretchr/testify/suite" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + + chain "github.com/comdex-official/comdex/app" + assetKeeper "github.com/comdex-official/comdex/x/asset/keeper" + lockerKeeper "github.com/comdex-official/comdex/x/locker/keeper" + lockerTypes "github.com/comdex-official/comdex/x/locker/types" +) + +type KeeperTestSuite struct { + suite.Suite + + app *chain.App + ctx sdk.Context + assetKeeper assetKeeper.Keeper + lockerKeeper lockerKeeper.Keeper + querier lockerKeeper.QueryServer + msgServer lockerTypes.MsgServer +} + +func TestKeeperTestSuite(t *testing.T) { + suite.Run(t, new(KeeperTestSuite)) +} + +func (s *KeeperTestSuite) SetupTest() { + s.app = chain.Setup(false) + s.ctx = s.app.BaseApp.NewContext(false, tmproto.Header{}) + s.lockerKeeper = s.app.LockerKeeper + s.assetKeeper = s.app.AssetKeeper + s.querier = lockerKeeper.QueryServer{Keeper: s.lockerKeeper} + s.msgServer = lockerKeeper.NewMsgServiceServer(s.lockerKeeper) +} + +// +//// Below are just shortcuts to frequently-used functions. +//func (s *KeeperTestSuite) getBalances(addr sdk.AccAddress) sdk.Coins { +// return s.app.bankKeeper.GetAllBalances(s.ctx, addr) +//} +// +//func (s *KeeperTestSuite) getBalance(addr sdk.AccAddress, denom string) sdk.Coin { +// return s.app.bankKeeper.GetBalance(s.ctx, addr, denom) +//} +// +//func (s *KeeperTestSuite) sendCoins(fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) { +// s.T().Helper() +// err := s.app.bankKeeper.SendCoins(s.ctx, fromAddr, toAddr, amt) +// s.Require().NoError(err) +//} +// +//func (s *KeeperTestSuite) nextBlock() { +// liquidity.EndBlocker(s.ctx, s.keeper) +// liquidity.BeginBlocker(s.ctx, s.keeper) +//} +// +//// Below are useful helpers to write test code easily. +//func (s *KeeperTestSuite) addr(addrNum int) sdk.AccAddress { +// addr := make(sdk.AccAddress, 20) +// binary.PutVarint(addr, int64(addrNum)) +// return addr +//} + +func (s *KeeperTestSuite) fundAddr(addr string, amt sdk.Coin) { + s.T().Helper() + err := s.app.BankKeeper.MintCoins(s.ctx, lockerTypes.ModuleName, sdk.NewCoins(amt)) + s.Require().NoError(err) + addr1, err := sdk.AccAddressFromBech32(addr) + err = s.app.BankKeeper.SendCoinsFromModuleToAccount(s.ctx, lockerTypes.ModuleName, addr1, sdk.NewCoins(amt)) + s.Require().NoError(err) +} + +func (s *KeeperTestSuite) advanceseconds(dur int64) { + s.ctx = s.ctx.WithBlockTime(s.ctx.BlockTime().Add(time.Second * time.Duration(dur))) + fmt.Println(s.ctx.BlockTime()) +} + +// ParseCoins parses and returns sdk.Coins. +func ParseCoin(s string) sdk.Coin { + coins, err := sdk.ParseCoinNormalized(s) + if err != nil { + panic(err) + } + return coins +} diff --git a/x/locker/keeper/locker.go b/x/locker/keeper/locker.go index cdb54bc48..89f6592ce 100644 --- a/x/locker/keeper/locker.go +++ b/x/locker/keeper/locker.go @@ -2,6 +2,7 @@ package keeper import ( "context" + // "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" grpctypes "github.com/cosmos/cosmos-sdk/types/grpc" diff --git a/x/locker/keeper/locker_test.go b/x/locker/keeper/locker_test.go new file mode 100644 index 000000000..f2421ee10 --- /dev/null +++ b/x/locker/keeper/locker_test.go @@ -0,0 +1,234 @@ +package keeper_test + +import ( + assetTypes "github.com/comdex-official/comdex/x/asset/types" + "github.com/comdex-official/comdex/x/locker/keeper" + lockerTypes "github.com/comdex-official/comdex/x/locker/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func (s *KeeperTestSuite) AddAppAsset() { + assetKeeper, ctx := &s.assetKeeper, &s.ctx + msg1 := []assetTypes.AppMapping{{ + Name: "cswap", + ShortName: "cswap", + MinGovDeposit: sdk.NewIntFromUint64(10000000), + GovTimeInSeconds: 900}, + { + Name: "commodo", + ShortName: "commodo", + MinGovDeposit: sdk.NewIntFromUint64(10000000), + GovTimeInSeconds: 900}, + } + err := assetKeeper.AddAppMappingRecords(*ctx, msg1...) + s.Require().NoError(err) + + msg2 := []assetTypes.Asset{ + {Name: "CMDX", + Denom: "ucmdx", + Decimals: 1000000, + IsOnchain: true}, {Name: "CMST", + Denom: "ucmst", + Decimals: 1000000, + IsOnchain: true}, {Name: "HARBOR", + Denom: "uharbor", + Decimals: 1000000, + IsOnchain: true}, + } + err = assetKeeper.AddAssetRecords(*ctx, msg2...) + s.Require().NoError(err) + +} + +func (s *KeeperTestSuite) TestCreateLocker() { + userAddress := "cosmos1q7q90qsl9g0gl2zz0njxwv2a649yqrtyxtnv3v" + lockerKeeper, ctx := &s.lockerKeeper, &s.ctx + s.AddAppAsset() + msg3 := lockerTypes.MsgAddWhiteListedAssetRequest{ + From: userAddress, + AppMappingId: 1, + AssetId: 1, + } + server := keeper.NewMsgServiceServer(*lockerKeeper) + _, err := server.MsgAddWhiteListedAsset(sdk.WrapSDKContext(*ctx), &msg3) + s.Require().NoError(err) + + msg4 := lockerTypes.MsgCreateLockerRequest{ + Depositor: userAddress, + Amount: sdk.NewIntFromUint64(1000000), + AssetId: 1, + AppMappingId: 1, + } + + //Insufficient balance check + _, err = server.MsgCreateLocker(sdk.WrapSDKContext(*ctx), &msg4) + s.Require().Error(err) + + //create locker for first asset + s.fundAddr(userAddress, sdk.NewCoin("ucmdx", sdk.NewIntFromUint64(1000000))) + _, err = server.MsgCreateLocker(sdk.WrapSDKContext(*ctx), &msg4) + s.Require().NoError(err) + + qmsg1 := lockerTypes.QueryLockerInfoRequest{ + Id: "cswap1", + } + lockerInfo, err := s.querier.QueryLockerInfo(sdk.WrapSDKContext(*ctx), &qmsg1) + s.Require().NoError(err) + s.Require().Equal(lockerInfo.LockerInfo.Depositor, msg4.Depositor) + s.Require().Equal(lockerInfo.LockerInfo.AppMappingId, msg4.AppMappingId) + s.Require().Equal(lockerInfo.LockerInfo.AssetDepositId, msg4.AssetId) + s.Require().Equal(lockerInfo.LockerInfo.NetBalance, msg4.Amount) + + //create locker two times on same asset should fail + _, err = server.MsgCreateLocker(sdk.WrapSDKContext(*ctx), &msg4) + s.Require().Error(err) + + //create locker for second asset + msg5 := lockerTypes.MsgAddWhiteListedAssetRequest{ + From: userAddress, + AppMappingId: 1, + AssetId: 2, + } + _, err = server.MsgAddWhiteListedAsset(sdk.WrapSDKContext(*ctx), &msg5) + s.Require().NoError(err) + msg6 := lockerTypes.MsgCreateLockerRequest{ + Depositor: userAddress, + Amount: sdk.NewIntFromUint64(2000000), + AssetId: 2, + AppMappingId: 1, + } + s.fundAddr(userAddress, sdk.NewCoin("ucmst", sdk.NewIntFromUint64(2000000))) + _, err = server.MsgCreateLocker(sdk.WrapSDKContext(*ctx), &msg6) + s.Require().NoError(err) + qmsg2 := lockerTypes.QueryLockerInfoRequest{ + Id: "cswap2", + } + lockerInfo, err = s.querier.QueryLockerInfo(sdk.WrapSDKContext(*ctx), &qmsg2) + s.Require().NoError(err) + s.Require().Equal(lockerInfo.LockerInfo.Depositor, msg6.Depositor) + s.Require().Equal(lockerInfo.LockerInfo.AppMappingId, msg6.AppMappingId) + s.Require().Equal(lockerInfo.LockerInfo.AssetDepositId, msg6.AssetId) + s.Require().Equal(lockerInfo.LockerInfo.NetBalance, msg6.Amount) + + //create locker for different app and same asset + + msg8 := lockerTypes.MsgAddWhiteListedAssetRequest{ + From: userAddress, + AppMappingId: 2, + AssetId: 1, + } + _, err = server.MsgAddWhiteListedAsset(sdk.WrapSDKContext(*ctx), &msg8) + s.Require().NoError(err) + + msg7 := lockerTypes.MsgCreateLockerRequest{ + Depositor: userAddress, + Amount: sdk.NewIntFromUint64(9900000), + AssetId: 1, + AppMappingId: 2, + } + + //Insufficient balance check + _, err = server.MsgCreateLocker(sdk.WrapSDKContext(*ctx), &msg7) + s.Require().Error(err) + + //create locker for first asset + s.fundAddr(userAddress, sdk.NewCoin("ucmdx", sdk.NewIntFromUint64(9900000))) + _, err = server.MsgCreateLocker(sdk.WrapSDKContext(*ctx), &msg7) + s.Require().NoError(err) + + qmsg3 := lockerTypes.QueryLockerInfoRequest{ + Id: "commodo1", + } + lockerInfo, err = s.querier.QueryLockerInfo(sdk.WrapSDKContext(*ctx), &qmsg3) + s.Require().NoError(err) + s.Require().Equal(lockerInfo.LockerInfo.Depositor, msg7.Depositor) + s.Require().Equal(lockerInfo.LockerInfo.AppMappingId, msg7.AppMappingId) + s.Require().Equal(lockerInfo.LockerInfo.AssetDepositId, msg7.AssetId) + s.Require().Equal(lockerInfo.LockerInfo.NetBalance, msg7.Amount) + +} + +func (s *KeeperTestSuite) TestDepositLocker() { + userAddress := "cosmos1q7q90qsl9g0gl2zz0njxwv2a649yqrtyxtnv3v" + lockerKeeper, ctx := &s.lockerKeeper, &s.ctx + //s.AddAppAsset() + s.TestCreateLocker() + msg1 := lockerTypes.MsgDepositAssetRequest{ + Depositor: userAddress, + LockerId: "cswap1", + Amount: sdk.NewIntFromUint64(4000000), + AssetId: 1, + AppMappingId: 1, + } + server := keeper.NewMsgServiceServer(*lockerKeeper) + + //Insufficient balance + _, err := server.MsgDepositAsset(sdk.WrapSDKContext(*ctx), &msg1) + s.Require().Error(err) + + //Deposit Asset + s.fundAddr(userAddress, sdk.NewCoin("ucmdx", sdk.NewIntFromUint64(4000000))) + _, err = server.MsgDepositAsset(sdk.WrapSDKContext(*ctx), &msg1) + s.Require().NoError(err) + qmsg1 := lockerTypes.QueryLockerInfoRequest{ + Id: "cswap1", + } + lockerInfo, err := s.querier.QueryLockerInfo(sdk.WrapSDKContext(*ctx), &qmsg1) + s.Require().NoError(err) + s.Require().Equal(lockerInfo.LockerInfo.Depositor, msg1.Depositor) + s.Require().Equal(lockerInfo.LockerInfo.AppMappingId, msg1.AppMappingId) + s.Require().Equal(lockerInfo.LockerInfo.AssetDepositId, msg1.AssetId) + s.Require().Equal(lockerInfo.LockerInfo.NetBalance, msg1.Amount.Add(sdk.NewIntFromUint64(1000000))) + +} + +func (s *KeeperTestSuite) TestWithdrawLocker() { + userAddress := "cosmos1q7q90qsl9g0gl2zz0njxwv2a649yqrtyxtnv3v" + lockerKeeper, ctx := &s.lockerKeeper, &s.ctx + //s.AddAppAsset() + s.TestCreateLocker() + msg1 := lockerTypes.MsgWithdrawAssetRequest{ + Depositor: userAddress, + LockerId: "cswap1", + Amount: sdk.NewIntFromUint64(10000000), + AssetId: 1, + AppMappingId: 1, + } + server := keeper.NewMsgServiceServer(*lockerKeeper) + + //Insufficient balance + _, err := server.MsgWithdrawAsset(sdk.WrapSDKContext(*ctx), &msg1) + s.Require().Error(err) + + //Partial Withdraw Asset + msg2 := lockerTypes.MsgWithdrawAssetRequest{ + Depositor: userAddress, + LockerId: "cswap1", + Amount: sdk.NewIntFromUint64(100000), + AssetId: 1, + AppMappingId: 1, + } + _, err = server.MsgWithdrawAsset(sdk.WrapSDKContext(*ctx), &msg2) + s.Require().NoError(err) + qmsg1 := lockerTypes.QueryLockerInfoRequest{ + Id: "cswap1", + } + lockerInfo, err := s.querier.QueryLockerInfo(sdk.WrapSDKContext(*ctx), &qmsg1) + s.Require().NoError(err) + s.Require().Equal(lockerInfo.LockerInfo.NetBalance, sdk.NewIntFromUint64(900000)) + + //Full Withdraw Asset + msg3 := lockerTypes.MsgWithdrawAssetRequest{ + Depositor: userAddress, + LockerId: "cswap1", + Amount: sdk.NewIntFromUint64(900000), + AssetId: 1, + AppMappingId: 1, + } + _, err = server.MsgWithdrawAsset(sdk.WrapSDKContext(*ctx), &msg3) + s.Require().NoError(err) + lockerInfo, err = s.querier.QueryLockerInfo(sdk.WrapSDKContext(*ctx), &qmsg1) + s.Require().NoError(err) + s.Require().Equal(lockerInfo.LockerInfo.NetBalance, sdk.NewIntFromUint64(0)) + +}