github.com/gravity-devs/liquidity@v1.5.3/x/liquidity/keeper/batch_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	sdk "github.com/cosmos/cosmos-sdk/types"
     7  	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
     8  	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"github.com/gravity-devs/liquidity/app"
    12  	"github.com/gravity-devs/liquidity/x/liquidity"
    13  	"github.com/gravity-devs/liquidity/x/liquidity/types"
    14  )
    15  
    16  const (
    17  	DenomX = "denomX"
    18  	DenomY = "denomY"
    19  	DenomA = "denomA"
    20  	DenomB = "denomB"
    21  )
    22  
    23  func TestBadDeposit(t *testing.T) {
    24  	simapp, ctx := app.CreateTestInput()
    25  	params := simapp.LiquidityKeeper.GetParams(ctx)
    26  
    27  	depositCoins := sdk.NewCoins(sdk.NewCoin(DenomX, params.MinInitDepositAmount), sdk.NewCoin(DenomY, params.MinInitDepositAmount))
    28  	depositorAddr := app.AddRandomTestAddr(simapp, ctx, depositCoins.Add(params.PoolCreationFee...))
    29  
    30  	pool, err := simapp.LiquidityKeeper.CreatePool(ctx, &types.MsgCreatePool{
    31  		PoolCreatorAddress: depositorAddr.String(),
    32  		PoolTypeId:         types.DefaultPoolTypeID,
    33  		DepositCoins:       depositCoins,
    34  	})
    35  	require.NoError(t, err)
    36  
    37  	// deposit with empty message
    38  	_, err = simapp.LiquidityKeeper.DepositWithinBatch(ctx, &types.MsgDepositWithinBatch{})
    39  	require.ErrorIs(t, err, types.ErrPoolNotExists)
    40  
    41  	// deposit coins more than it has
    42  	_, err = simapp.LiquidityKeeper.DepositWithinBatch(ctx, &types.MsgDepositWithinBatch{
    43  		DepositorAddress: depositorAddr.String(),
    44  		PoolId:           pool.Id,
    45  		DepositCoins:     sdk.NewCoins(sdk.NewCoin(DenomX, sdk.OneInt()), sdk.NewCoin(DenomY, sdk.OneInt())),
    46  	})
    47  	require.ErrorIs(t, err, sdkerrors.ErrInsufficientFunds)
    48  
    49  	// forcefully delete current pool batch
    50  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, pool.Id)
    51  	require.True(t, found)
    52  	simapp.LiquidityKeeper.DeletePoolBatch(ctx, batch)
    53  	// deposit coins when there is no pool batch
    54  	_, err = simapp.LiquidityKeeper.DepositWithinBatch(ctx, &types.MsgDepositWithinBatch{
    55  		DepositorAddress: depositorAddr.String(),
    56  		PoolId:           pool.Id,
    57  		DepositCoins:     sdk.NewCoins(sdk.NewCoin(DenomX, sdk.OneInt()), sdk.NewCoin(DenomY, sdk.OneInt())),
    58  	})
    59  	require.ErrorIs(t, err, types.ErrPoolBatchNotExists)
    60  }
    61  
    62  func TestBadWithdraw(t *testing.T) {
    63  	simapp, ctx := app.CreateTestInput()
    64  	params := simapp.LiquidityKeeper.GetParams(ctx)
    65  
    66  	depositCoins := sdk.NewCoins(sdk.NewCoin(DenomX, params.MinInitDepositAmount), sdk.NewCoin(DenomY, params.MinInitDepositAmount))
    67  	depositorAddr := app.AddRandomTestAddr(simapp, ctx, depositCoins.Add(params.PoolCreationFee...))
    68  
    69  	pool, err := simapp.LiquidityKeeper.CreatePool(ctx, &types.MsgCreatePool{
    70  		PoolCreatorAddress: depositorAddr.String(),
    71  		PoolTypeId:         types.DefaultPoolTypeID,
    72  		DepositCoins:       depositCoins,
    73  	})
    74  	require.NoError(t, err)
    75  
    76  	// withdraw with empty message
    77  	_, err = simapp.LiquidityKeeper.WithdrawWithinBatch(ctx, &types.MsgWithdrawWithinBatch{})
    78  	require.ErrorIs(t, err, types.ErrPoolNotExists)
    79  
    80  	balance := simapp.BankKeeper.GetBalance(ctx, depositorAddr, pool.PoolCoinDenom)
    81  
    82  	// mint extra pool coins to test if below fails
    83  	require.NoError(t, simapp.BankKeeper.MintCoins(ctx, types.ModuleName, sdk.NewCoins(sdk.NewCoin(pool.PoolCoinDenom, sdk.NewInt(1000)))))
    84  	// withdraw pool coins more than it has
    85  	_, err = simapp.LiquidityKeeper.WithdrawWithinBatch(ctx, &types.MsgWithdrawWithinBatch{
    86  		WithdrawerAddress: depositorAddr.String(),
    87  		PoolId:            pool.Id,
    88  		PoolCoin:          balance.Add(sdk.NewCoin(pool.PoolCoinDenom, sdk.OneInt())),
    89  	})
    90  	require.ErrorIs(t, err, sdkerrors.ErrInsufficientFunds)
    91  
    92  	// forcefully delete current pool batch
    93  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, pool.Id)
    94  	require.True(t, found)
    95  	simapp.LiquidityKeeper.DeletePoolBatch(ctx, batch)
    96  	// withdraw pool coins when there is no pool batch
    97  	_, err = simapp.LiquidityKeeper.WithdrawWithinBatch(ctx, &types.MsgWithdrawWithinBatch{
    98  		WithdrawerAddress: depositorAddr.String(),
    99  		PoolId:            pool.Id,
   100  		PoolCoin:          sdk.NewCoin(pool.PoolCoinDenom, sdk.OneInt()),
   101  	})
   102  	require.ErrorIs(t, err, types.ErrPoolBatchNotExists)
   103  }
   104  
   105  func TestBadSwap(t *testing.T) {
   106  	simapp, ctx := app.CreateTestInput()
   107  	params := simapp.LiquidityKeeper.GetParams(ctx)
   108  
   109  	depositCoins := sdk.NewCoins(sdk.NewCoin(DenomX, params.MinInitDepositAmount), sdk.NewCoin(DenomY, params.MinInitDepositAmount))
   110  	depositorAddr := app.AddRandomTestAddr(simapp, ctx, depositCoins.Add(params.PoolCreationFee...))
   111  
   112  	pool, err := simapp.LiquidityKeeper.CreatePool(ctx, &types.MsgCreatePool{
   113  		PoolCreatorAddress: depositorAddr.String(),
   114  		PoolTypeId:         types.DefaultPoolTypeID,
   115  		DepositCoins:       depositCoins,
   116  	})
   117  	require.NoError(t, err)
   118  
   119  	// swap with empty message
   120  	_, err = simapp.LiquidityKeeper.SwapWithinBatch(ctx, &types.MsgSwapWithinBatch{}, 0)
   121  	require.ErrorIs(t, err, types.ErrPoolNotExists)
   122  
   123  	orderPrice := sdk.OneDec()
   124  
   125  	// swap coin more than it has
   126  	offerCoin := sdk.NewCoin(DenomX, sdk.NewInt(100000))
   127  	_, err = simapp.LiquidityKeeper.SwapWithinBatch(ctx, &types.MsgSwapWithinBatch{
   128  		SwapRequesterAddress: depositorAddr.String(),
   129  		PoolId:               pool.Id,
   130  		SwapTypeId:           types.DefaultSwapTypeID,
   131  		OfferCoin:            offerCoin,
   132  		DemandCoinDenom:      DenomY,
   133  		OfferCoinFee:         types.GetOfferCoinFee(offerCoin, params.SwapFeeRate),
   134  		OrderPrice:           orderPrice,
   135  	}, 0)
   136  	require.ErrorIs(t, err, sdkerrors.ErrInsufficientFunds)
   137  
   138  	// when swap fails, user's balance should never change
   139  	app.SaveAccount(simapp, ctx, depositorAddr, sdk.NewCoins(offerCoin))
   140  	_, err = simapp.LiquidityKeeper.SwapWithinBatch(ctx, &types.MsgSwapWithinBatch{
   141  		SwapRequesterAddress: depositorAddr.String(),
   142  		PoolId:               pool.Id,
   143  		SwapTypeId:           types.DefaultSwapTypeID,
   144  		OfferCoin:            offerCoin,
   145  		DemandCoinDenom:      DenomY,
   146  		OfferCoinFee:         types.GetOfferCoinFee(offerCoin, params.SwapFeeRate),
   147  		OrderPrice:           orderPrice,
   148  	}, 0)
   149  	require.ErrorIs(t, err, sdkerrors.ErrInsufficientFunds)
   150  	balance := simapp.BankKeeper.GetBalance(ctx, depositorAddr, DenomX)
   151  	require.Equal(t, offerCoin, balance)
   152  
   153  	// forcefully delete current pool batch
   154  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, pool.Id)
   155  	require.True(t, found)
   156  	simapp.LiquidityKeeper.DeletePoolBatch(ctx, batch)
   157  	// swap coin when there is no pool batch
   158  	_, err = simapp.LiquidityKeeper.SwapWithinBatch(ctx, &types.MsgSwapWithinBatch{
   159  		SwapRequesterAddress: depositorAddr.String(),
   160  		PoolId:               pool.Id,
   161  		SwapTypeId:           types.DefaultSwapTypeID,
   162  		OfferCoin:            offerCoin,
   163  		DemandCoinDenom:      DenomY,
   164  		OfferCoinFee:         types.GetOfferCoinFee(offerCoin, params.SwapFeeRate),
   165  		OrderPrice:           orderPrice,
   166  	}, 0)
   167  	require.ErrorIs(t, err, types.ErrPoolBatchNotExists)
   168  }
   169  
   170  func TestCreateDepositWithdrawWithinBatch(t *testing.T) {
   171  	simapp, ctx := createTestInput()
   172  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   173  	params := simapp.LiquidityKeeper.GetParams(ctx)
   174  
   175  	// define test denom X, Y for Liquidity Pool
   176  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   177  	denomA, denomB := types.AlphabeticalDenomPair(DenomA, DenomB)
   178  
   179  	X := sdk.NewInt(1000000000)
   180  	Y := sdk.NewInt(1000000000)
   181  	deposit := sdk.NewCoins(sdk.NewCoin(denomX, X), sdk.NewCoin(denomY, Y))
   182  
   183  	A := sdk.NewInt(1000000000000)
   184  	B := sdk.NewInt(1000000000000)
   185  	depositAB := sdk.NewCoins(sdk.NewCoin(denomA, A), sdk.NewCoin(denomB, B))
   186  
   187  	// set accounts for creator, depositor, withdrawer, balance for deposit
   188  	addrs := app.AddTestAddrs(simapp, ctx, 4, params.PoolCreationFee)
   189  
   190  	app.SaveAccount(simapp, ctx, addrs[0], deposit.Add(depositAB...)) // pool creator
   191  	depositX := simapp.BankKeeper.GetBalance(ctx, addrs[0], denomX)
   192  	depositY := simapp.BankKeeper.GetBalance(ctx, addrs[0], denomY)
   193  	depositBalance := sdk.NewCoins(depositX, depositY)
   194  	depositA := simapp.BankKeeper.GetBalance(ctx, addrs[0], DenomA)
   195  	depositB := simapp.BankKeeper.GetBalance(ctx, addrs[0], denomB)
   196  	depositBalanceAB := sdk.NewCoins(depositA, depositB)
   197  	require.Equal(t, deposit, depositBalance)
   198  	require.Equal(t, depositAB, depositBalanceAB)
   199  	feePoolAcc := simapp.AccountKeeper.GetModuleAddress(distrtypes.ModuleName)
   200  	feePoolBalance := simapp.BankKeeper.GetAllBalances(ctx, feePoolAcc)
   201  
   202  	// Success case, create Liquidity pool
   203  	poolTypeID := types.DefaultPoolTypeID
   204  	msg := types.NewMsgCreatePool(addrs[0], poolTypeID, depositBalance)
   205  	_, err := simapp.LiquidityKeeper.CreatePool(ctx, msg)
   206  	require.NoError(t, err)
   207  
   208  	// Verify PoolCreationFee pay successfully
   209  	feePoolBalance = feePoolBalance.Add(params.PoolCreationFee...)
   210  	require.Equal(t, params.PoolCreationFee, feePoolBalance)
   211  
   212  	// Fail case, reset deposit balance for pool already exists case
   213  	app.SaveAccount(simapp, ctx, addrs[0], deposit)
   214  	_, err = simapp.LiquidityKeeper.CreatePool(ctx, msg)
   215  	require.ErrorIs(t, err, types.ErrPoolAlreadyExists)
   216  
   217  	// reset deposit balance without PoolCreationFee of pool creator
   218  	// Fail case, insufficient balances for pool creation fee case
   219  	msgAB := types.NewMsgCreatePool(addrs[0], poolTypeID, depositBalanceAB)
   220  	app.SaveAccount(simapp, ctx, addrs[0], depositAB)
   221  	_, err = simapp.LiquidityKeeper.CreatePool(ctx, msgAB)
   222  	require.ErrorIs(t, types.ErrInsufficientPoolCreationFee, err)
   223  
   224  	// Success case, create another pool
   225  	msgAB = types.NewMsgCreatePool(addrs[0], poolTypeID, depositBalanceAB)
   226  	app.SaveAccount(simapp, ctx, addrs[0], depositAB.Add(params.PoolCreationFee...))
   227  	_, err = simapp.LiquidityKeeper.CreatePool(ctx, msgAB)
   228  	require.NoError(t, err)
   229  
   230  	// Verify PoolCreationFee pay successfully
   231  	feePoolBalance = simapp.BankKeeper.GetAllBalances(ctx, feePoolAcc)
   232  	require.Equal(t, params.PoolCreationFee.Add(params.PoolCreationFee...), feePoolBalance)
   233  
   234  	// verify created liquidity pool
   235  	pools := simapp.LiquidityKeeper.GetAllPools(ctx)
   236  	poolID := pools[0].Id
   237  	require.Equal(t, 2, len(pools))
   238  	//require.Equal(t, uint64(1), poolID)
   239  	require.Equal(t, denomX, pools[0].ReserveCoinDenoms[0])
   240  	require.Equal(t, denomY, pools[0].ReserveCoinDenoms[1])
   241  
   242  	// verify minted pool coin
   243  	poolCoin := simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   244  	creatorBalance := simapp.BankKeeper.GetBalance(ctx, addrs[0], pools[0].PoolCoinDenom)
   245  	require.Equal(t, poolCoin, creatorBalance.Amount)
   246  
   247  	// begin block, init
   248  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   249  
   250  	// set pool depositor account
   251  	app.SaveAccount(simapp, ctx, addrs[1], deposit) // pool creator
   252  	depositX = simapp.BankKeeper.GetBalance(ctx, addrs[1], denomX)
   253  	depositY = simapp.BankKeeper.GetBalance(ctx, addrs[1], denomY)
   254  	depositBalance = sdk.NewCoins(depositX, depositY)
   255  	require.Equal(t, deposit, depositBalance)
   256  
   257  	depositMsg := types.NewMsgDepositWithinBatch(addrs[1], poolID, depositBalance)
   258  	_, err = simapp.LiquidityKeeper.DepositWithinBatch(ctx, depositMsg)
   259  	require.NoError(t, err)
   260  
   261  	depositorBalanceX := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   262  	depositorBalanceY := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   263  	poolCoin = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   264  	require.Equal(t, sdk.ZeroInt(), depositorBalanceX.Amount)
   265  	require.Equal(t, sdk.ZeroInt(), depositorBalanceY.Amount)
   266  	require.Equal(t, denomX, depositorBalanceX.Denom)
   267  	require.Equal(t, denomY, depositorBalanceY.Denom)
   268  	require.Equal(t, poolCoin, creatorBalance.Amount)
   269  
   270  	// check escrow balance of module account
   271  	moduleAccAddress := simapp.AccountKeeper.GetModuleAddress(types.ModuleName)
   272  	moduleAccEscrowAmtX := simapp.BankKeeper.GetBalance(ctx, moduleAccAddress, denomX)
   273  	moduleAccEscrowAmtY := simapp.BankKeeper.GetBalance(ctx, moduleAccAddress, denomY)
   274  	require.Equal(t, depositX, moduleAccEscrowAmtX)
   275  	require.Equal(t, depositY, moduleAccEscrowAmtY)
   276  
   277  	// endblock
   278  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   279  
   280  	// verify minted pool coin
   281  	poolCoin = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   282  	depositorPoolCoinBalance := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].PoolCoinDenom)
   283  	require.NotEqual(t, sdk.ZeroInt(), depositBalance)
   284  	require.Equal(t, poolCoin, depositorPoolCoinBalance.Amount.Add(creatorBalance.Amount))
   285  
   286  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
   287  	require.True(t, found)
   288  	msgs := simapp.LiquidityKeeper.GetAllPoolBatchDepositMsgs(ctx, batch)
   289  	require.Len(t, msgs, 1)
   290  	require.True(t, msgs[0].Executed)
   291  	require.True(t, msgs[0].Succeeded)
   292  	require.True(t, msgs[0].ToBeDeleted)
   293  	require.Equal(t, uint64(1), batch.Index)
   294  
   295  	// error balance after endblock
   296  	depositorBalanceX = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   297  	depositorBalanceY = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   298  	require.Equal(t, sdk.ZeroInt(), depositorBalanceX.Amount)
   299  	require.Equal(t, sdk.ZeroInt(), depositorBalanceY.Amount)
   300  	require.Equal(t, denomX, depositorBalanceX.Denom)
   301  	require.Equal(t, denomY, depositorBalanceY.Denom)
   302  	// next block
   303  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   304  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   305  	depositorBalanceX = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   306  	depositorBalanceY = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   307  	require.Equal(t, sdk.ZeroInt(), depositorBalanceX.Amount)
   308  	require.Equal(t, sdk.ZeroInt(), depositorBalanceY.Amount)
   309  	require.Equal(t, denomX, depositorBalanceX.Denom)
   310  	require.Equal(t, denomY, depositorBalanceY.Denom)
   311  	// msg deleted
   312  	_, found = simapp.LiquidityKeeper.GetPoolBatchDepositMsgState(ctx, poolID, msgs[0].MsgIndex)
   313  	require.False(t, found)
   314  
   315  	msgs = simapp.LiquidityKeeper.GetAllPoolBatchDepositMsgs(ctx, batch)
   316  	require.Len(t, msgs, 0)
   317  
   318  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, batch.PoolId)
   319  	require.True(t, found)
   320  	require.Equal(t, uint64(2), batch.Index)
   321  
   322  	// withdraw
   323  	withdrawerBalanceX := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   324  	withdrawerBalanceY := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   325  	withdrawerBalancePoolCoinBefore := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].PoolCoinDenom)
   326  	moduleAccEscrowAmtPool := simapp.BankKeeper.GetBalance(ctx, moduleAccAddress, pools[0].PoolCoinDenom)
   327  	require.Equal(t, sdk.ZeroInt(), moduleAccEscrowAmtPool.Amount)
   328  	withdrawMsg := types.NewMsgWithdrawWithinBatch(addrs[1], poolID, withdrawerBalancePoolCoinBefore)
   329  	_, err = simapp.LiquidityKeeper.WithdrawWithinBatch(ctx, withdrawMsg)
   330  	require.NoError(t, err)
   331  
   332  	withdrawerBalanceX = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   333  	withdrawerBalanceY = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   334  	withdrawerBalancePoolCoin := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].PoolCoinDenom)
   335  	poolCoin = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   336  	require.Equal(t, sdk.ZeroInt(), withdrawerBalanceX.Amount)
   337  	require.Equal(t, sdk.ZeroInt(), withdrawerBalanceY.Amount)
   338  	require.Equal(t, sdk.ZeroInt(), withdrawerBalancePoolCoin.Amount)
   339  	require.Equal(t, poolCoin, creatorBalance.Amount.Add(depositorPoolCoinBalance.Amount))
   340  
   341  	// check escrow balance of module account
   342  	moduleAccEscrowAmtPool = simapp.BankKeeper.GetBalance(ctx, moduleAccAddress, pools[0].PoolCoinDenom)
   343  	require.Equal(t, withdrawerBalancePoolCoinBefore, moduleAccEscrowAmtPool)
   344  
   345  	// endblock
   346  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   347  
   348  	// verify burned pool coin
   349  	poolCoin = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   350  	withdrawerBalanceX = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   351  	withdrawerBalanceY = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   352  	withdrawerBalancePoolCoin = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].PoolCoinDenom)
   353  	require.Equal(t, depositX.Amount.ToDec().Mul(sdk.OneDec().Sub(params.WithdrawFeeRate)).TruncateInt(), withdrawerBalanceX.Amount)
   354  	require.Equal(t, depositY.Amount.ToDec().Mul(sdk.OneDec().Sub(params.WithdrawFeeRate)).TruncateInt(), withdrawerBalanceY.Amount)
   355  	require.Equal(t, sdk.ZeroInt(), withdrawerBalancePoolCoin.Amount)
   356  	require.Equal(t, poolCoin, creatorBalance.Amount)
   357  
   358  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
   359  	require.True(t, found)
   360  	withdrawMsgs := simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
   361  	require.Len(t, withdrawMsgs, 1)
   362  	require.True(t, withdrawMsgs[0].Executed)
   363  	require.True(t, withdrawMsgs[0].Succeeded)
   364  	require.True(t, withdrawMsgs[0].ToBeDeleted)
   365  	require.Equal(t, uint64(2), batch.Index)
   366  
   367  	// next block
   368  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   369  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   370  
   371  	// msg deleted
   372  	withdrawMsgs = simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
   373  	require.Len(t, withdrawMsgs, 0)
   374  	_, found = simapp.LiquidityKeeper.GetPoolBatchWithdrawMsgState(ctx, poolID, 0)
   375  	require.False(t, found)
   376  
   377  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, batch.PoolId)
   378  	require.True(t, found)
   379  	require.Equal(t, uint64(3), batch.Index)
   380  	require.False(t, batch.Executed)
   381  }
   382  
   383  func TestCreateDepositWithdrawWithinBatch2(t *testing.T) {
   384  	simapp, ctx := createTestInput()
   385  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   386  
   387  	// define test denom X, Y for Liquidity Pool
   388  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   389  
   390  	X := sdk.NewInt(1000000000)
   391  	Y := sdk.NewInt(1000000000)
   392  	deposit := sdk.NewCoins(sdk.NewCoin(denomX, X), sdk.NewCoin(denomY, Y))
   393  	deposit2 := sdk.NewCoins(sdk.NewCoin(denomX, X.QuoRaw(2)), sdk.NewCoin(denomY, Y.QuoRaw(2)))
   394  
   395  	// set accounts for creator, depositor, withdrawer, balance for deposit
   396  	params := simapp.LiquidityKeeper.GetParams(ctx)
   397  	addrs := app.AddTestAddrs(simapp, ctx, 3, params.PoolCreationFee)
   398  	app.SaveAccount(simapp, ctx, addrs[0], deposit) // pool creator
   399  	depositX := simapp.BankKeeper.GetBalance(ctx, addrs[0], denomX)
   400  	depositY := simapp.BankKeeper.GetBalance(ctx, addrs[0], denomY)
   401  	depositBalance := sdk.NewCoins(depositX, depositY)
   402  	require.Equal(t, deposit, depositBalance)
   403  
   404  	// create Liquidity pool
   405  	poolTypeID := types.DefaultPoolTypeID
   406  	msg := types.NewMsgCreatePool(addrs[0], poolTypeID, depositBalance)
   407  	_, err := simapp.LiquidityKeeper.CreatePool(ctx, msg)
   408  	require.NoError(t, err)
   409  
   410  	// verify created liquidity pool
   411  	pools := simapp.LiquidityKeeper.GetAllPools(ctx)
   412  	poolID := pools[0].Id
   413  	require.Equal(t, 1, len(pools))
   414  	require.Equal(t, uint64(1), poolID)
   415  	require.Equal(t, denomX, pools[0].ReserveCoinDenoms[0])
   416  	require.Equal(t, denomY, pools[0].ReserveCoinDenoms[1])
   417  
   418  	// verify minted pool coin
   419  	poolCoin := simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   420  	creatorBalance := simapp.BankKeeper.GetBalance(ctx, addrs[0], pools[0].PoolCoinDenom)
   421  	require.Equal(t, poolCoin, creatorBalance.Amount)
   422  
   423  	// begin block, init
   424  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   425  
   426  	// set pool depositor account
   427  	app.SaveAccount(simapp, ctx, addrs[1], deposit2) // pool creator
   428  	depositX = simapp.BankKeeper.GetBalance(ctx, addrs[1], denomX)
   429  	depositY = simapp.BankKeeper.GetBalance(ctx, addrs[1], denomY)
   430  	depositBalance = sdk.NewCoins(depositX, depositY)
   431  	require.Equal(t, deposit2, depositBalance)
   432  
   433  	depositMsg := types.NewMsgDepositWithinBatch(addrs[1], poolID, depositBalance)
   434  	_, err = simapp.LiquidityKeeper.DepositWithinBatch(ctx, depositMsg)
   435  	require.NoError(t, err)
   436  
   437  	depositorBalanceX := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   438  	depositorBalanceY := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   439  	poolCoin = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   440  	require.Equal(t, sdk.ZeroInt(), depositorBalanceX.Amount)
   441  	require.Equal(t, sdk.ZeroInt(), depositorBalanceY.Amount)
   442  	require.Equal(t, denomX, depositorBalanceX.Denom)
   443  	require.Equal(t, denomY, depositorBalanceY.Denom)
   444  	require.Equal(t, poolCoin, creatorBalance.Amount)
   445  
   446  	// check escrow balance of module account
   447  	moduleAccAddress := simapp.AccountKeeper.GetModuleAddress(types.ModuleName)
   448  	moduleAccEscrowAmtX := simapp.BankKeeper.GetBalance(ctx, moduleAccAddress, denomX)
   449  	moduleAccEscrowAmtY := simapp.BankKeeper.GetBalance(ctx, moduleAccAddress, denomY)
   450  	require.Equal(t, depositX, moduleAccEscrowAmtX)
   451  	require.Equal(t, depositY, moduleAccEscrowAmtY)
   452  
   453  	// endblock
   454  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   455  
   456  	// verify minted pool coin
   457  	poolCoin = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   458  	depositorPoolCoinBalance := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].PoolCoinDenom)
   459  	require.NotEqual(t, sdk.ZeroInt(), depositBalance)
   460  	require.Equal(t, poolCoin, depositorPoolCoinBalance.Amount.Add(creatorBalance.Amount))
   461  
   462  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
   463  	require.True(t, found)
   464  	msgs := simapp.LiquidityKeeper.GetAllPoolBatchDepositMsgs(ctx, batch)
   465  	require.Len(t, msgs, 1)
   466  	require.True(t, msgs[0].Executed)
   467  	require.True(t, msgs[0].Succeeded)
   468  	require.True(t, msgs[0].ToBeDeleted)
   469  	require.Equal(t, uint64(1), batch.Index)
   470  
   471  	// error balance after endblock
   472  	depositorBalanceX = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   473  	depositorBalanceY = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   474  	require.Equal(t, sdk.ZeroInt(), depositorBalanceX.Amount)
   475  	require.Equal(t, sdk.ZeroInt(), depositorBalanceY.Amount)
   476  	require.Equal(t, denomX, depositorBalanceX.Denom)
   477  	require.Equal(t, denomY, depositorBalanceY.Denom)
   478  
   479  	// next block
   480  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   481  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   482  	depositorBalanceX = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   483  	depositorBalanceY = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   484  	require.Equal(t, sdk.ZeroInt(), depositorBalanceX.Amount)
   485  	require.Equal(t, sdk.ZeroInt(), depositorBalanceY.Amount)
   486  	require.Equal(t, denomX, depositorBalanceX.Denom)
   487  	require.Equal(t, denomY, depositorBalanceY.Denom)
   488  	// msg deleted
   489  	_, found = simapp.LiquidityKeeper.GetPoolBatchDepositMsgState(ctx, poolID, msgs[0].MsgIndex)
   490  	require.False(t, found)
   491  
   492  	msgs = simapp.LiquidityKeeper.GetAllPoolBatchDepositMsgs(ctx, batch)
   493  	require.Len(t, msgs, 0)
   494  
   495  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, batch.PoolId)
   496  	require.True(t, found)
   497  	require.Equal(t, uint64(2), batch.Index)
   498  
   499  	// withdraw
   500  	withdrawerBalanceX := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   501  	withdrawerBalanceY := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   502  	withdrawerBalancePoolCoinBefore := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].PoolCoinDenom)
   503  	moduleAccEscrowAmtPool := simapp.BankKeeper.GetBalance(ctx, moduleAccAddress, pools[0].PoolCoinDenom)
   504  	require.Equal(t, sdk.ZeroInt(), moduleAccEscrowAmtPool.Amount)
   505  	withdrawMsg := types.NewMsgWithdrawWithinBatch(addrs[1], poolID, withdrawerBalancePoolCoinBefore)
   506  	_, err = simapp.LiquidityKeeper.WithdrawWithinBatch(ctx, withdrawMsg)
   507  	require.NoError(t, err)
   508  
   509  	withdrawerBalanceX = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   510  	withdrawerBalanceY = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   511  	withdrawerBalancePoolCoin := simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].PoolCoinDenom)
   512  	poolCoin = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   513  	require.Equal(t, sdk.ZeroInt(), withdrawerBalanceX.Amount)
   514  	require.Equal(t, sdk.ZeroInt(), withdrawerBalanceY.Amount)
   515  	require.Equal(t, sdk.ZeroInt(), withdrawerBalancePoolCoin.Amount)
   516  	require.Equal(t, poolCoin, creatorBalance.Amount.Add(depositorPoolCoinBalance.Amount))
   517  
   518  	// check escrow balance of module account
   519  	moduleAccEscrowAmtPool = simapp.BankKeeper.GetBalance(ctx, moduleAccAddress, pools[0].PoolCoinDenom)
   520  	require.Equal(t, withdrawerBalancePoolCoinBefore, moduleAccEscrowAmtPool)
   521  
   522  	// endblock
   523  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   524  
   525  	// verify burned pool coin
   526  	poolCoin = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pools[0])
   527  	withdrawerBalanceX = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[0])
   528  	withdrawerBalanceY = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].ReserveCoinDenoms[1])
   529  	withdrawerBalancePoolCoin = simapp.BankKeeper.GetBalance(ctx, addrs[1], pools[0].PoolCoinDenom)
   530  	require.Equal(t, depositX.Amount.ToDec().Mul(sdk.OneDec().Sub(params.WithdrawFeeRate)).TruncateInt(), withdrawerBalanceX.Amount)
   531  	require.Equal(t, depositY.Amount.ToDec().Mul(sdk.OneDec().Sub(params.WithdrawFeeRate)).TruncateInt(), withdrawerBalanceY.Amount)
   532  	require.Equal(t, sdk.ZeroInt(), withdrawerBalancePoolCoin.Amount)
   533  	require.Equal(t, poolCoin, creatorBalance.Amount)
   534  
   535  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
   536  	require.True(t, found)
   537  	withdrawMsgs := simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
   538  	require.Len(t, withdrawMsgs, 1)
   539  	require.True(t, withdrawMsgs[0].Executed)
   540  	require.True(t, withdrawMsgs[0].Succeeded)
   541  	require.True(t, withdrawMsgs[0].ToBeDeleted)
   542  	require.Equal(t, uint64(2), batch.Index)
   543  
   544  	// next block
   545  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   546  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   547  
   548  	// msg deleted
   549  	withdrawMsgs = simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
   550  	require.Len(t, withdrawMsgs, 0)
   551  	_, found = simapp.LiquidityKeeper.GetPoolBatchWithdrawMsgState(ctx, poolID, 0)
   552  	require.False(t, found)
   553  
   554  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, batch.PoolId)
   555  	require.True(t, found)
   556  	require.Equal(t, uint64(3), batch.Index)
   557  	require.False(t, batch.Executed)
   558  }
   559  
   560  // This scenario tests simple create pool, deposit to the pool, and withdraw from the pool
   561  func TestLiquidityScenario(t *testing.T) {
   562  	simapp, ctx := createTestInput()
   563  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   564  
   565  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   566  
   567  	X := sdk.NewInt(1000000000)
   568  	Y := sdk.NewInt(1000000000)
   569  
   570  	// create 20 random accounts with an initial balance of 0.01
   571  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   572  
   573  	// create two pools with the different denomY of 1000X and 1000Y coins
   574  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   575  	poolId2 := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, "testDenom", addrs[0])
   576  	require.Equal(t, uint64(1), poolID)
   577  	require.Equal(t, uint64(2), poolId2)
   578  
   579  	app.TestDepositPool(t, simapp, ctx, X, Y, addrs[1:10], poolID, true)
   580  
   581  	// next block starts
   582  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   583  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   584  
   585  	_, found := simapp.LiquidityKeeper.GetPool(ctx, poolID)
   586  	require.True(t, found)
   587  
   588  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
   589  	require.True(t, found)
   590  
   591  	// deposit message is expected to be handled
   592  	msgs := simapp.LiquidityKeeper.GetAllPoolBatchDepositMsgs(ctx, batch)
   593  	require.Len(t, msgs, 0)
   594  
   595  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(500000), addrs[1:10], poolID, true)
   596  
   597  	// next block
   598  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   599  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   600  
   601  	// withdraw message is expected to be handled
   602  	withdrawMsgs := simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
   603  	require.Len(t, withdrawMsgs, 0)
   604  
   605  	_, found = simapp.LiquidityKeeper.GetPoolBatchWithdrawMsgState(ctx, poolID, 0)
   606  	require.False(t, found)
   607  
   608  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, batch.PoolId)
   609  	require.True(t, found)
   610  	require.Equal(t, uint64(3), batch.Index)
   611  	require.False(t, batch.Executed)
   612  }
   613  
   614  // This scenario tests create pool, deposit to the pool, and swap coins
   615  func TestLiquidityScenario2(t *testing.T) {
   616  	simapp, ctx := createTestInput()
   617  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   618  
   619  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   620  
   621  	X := sdk.NewInt(1000000000)
   622  	Y := sdk.NewInt(1000000000)
   623  
   624  	// create 20 random accounts with an initial balance of 0.01
   625  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   626  
   627  	// create pool with 1000X and 1000Y coins
   628  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   629  	require.Equal(t, uint64(1), poolID)
   630  
   631  	// make two different deposits to the same pool with different amounts of coins
   632  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, true)
   633  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, true)
   634  
   635  	// next block
   636  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   637  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   638  
   639  	price, _ := sdk.NewDecFromStr("1.1")
   640  
   641  	offerCoinList := []sdk.Coin{sdk.NewCoin(denomX, sdk.NewInt(10000))}
   642  	orderPriceList := []sdk.Dec{price}
   643  	orderAddrList := addrs[1:2]
   644  
   645  	app.TestSwapPool(t, simapp, ctx, offerCoinList, orderPriceList, orderAddrList, poolID, false)
   646  	app.TestSwapPool(t, simapp, ctx, offerCoinList, orderPriceList, orderAddrList, poolID, false)
   647  	app.TestSwapPool(t, simapp, ctx, offerCoinList, orderPriceList, orderAddrList, poolID, false)
   648  	app.TestSwapPool(t, simapp, ctx, offerCoinList, orderPriceList, orderAddrList, poolID, true)
   649  }
   650  
   651  // This scenario tests to executed accumulated deposit and withdraw pool batches
   652  func TestLiquidityScenario3(t *testing.T) {
   653  	simapp, ctx := createTestInput()
   654  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   655  
   656  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   657  
   658  	X := sdk.NewInt(1000000000)
   659  	Y := sdk.NewInt(500000000)
   660  
   661  	// create 20 random accounts with an initial balance of 0.01
   662  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   663  
   664  	// create pool with 1000X and 500Y coins
   665  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   666  
   667  	// make 6 different deposits to the same pool with different amounts of coins
   668  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
   669  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
   670  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
   671  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
   672  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
   673  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
   674  
   675  	// execute accumulated deposit batches
   676  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   677  
   678  	// next block
   679  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   680  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   681  
   682  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(5000), addrs[1:2], poolID, false)
   683  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(500), addrs[1:2], poolID, false)
   684  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(50), addrs[1:2], poolID, false)
   685  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(5000), addrs[2:3], poolID, false)
   686  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(500), addrs[2:3], poolID, false)
   687  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(50), addrs[2:3], poolID, false)
   688  
   689  	// execute accumulated withdraw batches
   690  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   691  
   692  	// next block
   693  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   694  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   695  }
   696  
   697  // This scenario tests deposit refund scenario
   698  func TestDepositRefundTooSmallDepositAmount(t *testing.T) {
   699  	simapp, ctx := createTestInput()
   700  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   701  
   702  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   703  
   704  	X := sdk.NewInt(1000000000)
   705  	Y := sdk.NewInt(500000000)
   706  
   707  	// create 20 random accounts with an initial balance of 0.01
   708  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   709  
   710  	// create pool with 1000X and 500Y coins
   711  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   712  
   713  	app.TestDepositPool(t, simapp, ctx, sdk.OneInt(), sdk.OneInt(), addrs[1:2], poolID, false)
   714  
   715  	// balance should be zero since accounts' balances are expected to be in an escrow account
   716  	balanceX := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomX)
   717  	balanceY := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomY)
   718  	require.Equal(t, sdk.ZeroInt(), balanceX.Amount)
   719  	require.Equal(t, sdk.ZeroInt(), balanceY.Amount)
   720  
   721  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   722  
   723  	balanceXRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomX)
   724  	balanceYRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomY)
   725  	require.True(sdk.IntEq(t, sdk.OneInt(), balanceXRefunded.Amount))
   726  	require.True(sdk.IntEq(t, sdk.OneInt(), balanceYRefunded.Amount))
   727  
   728  	// next block
   729  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   730  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   731  }
   732  
   733  // This scenario tests deposit refund scenario
   734  func TestDepositRefundDeletedPool(t *testing.T) {
   735  	simapp, ctx := createTestInput()
   736  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   737  
   738  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   739  
   740  	X := sdk.NewInt(1000000000)
   741  	Y := sdk.NewInt(500000000)
   742  
   743  	// create 20 random accounts with an initial balance of 0.01
   744  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   745  
   746  	// create pool with 1000X and 500Y coins
   747  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   748  
   749  	app.TestDepositPool(t, simapp, ctx, X, Y, addrs[1:2], poolID, false)
   750  
   751  	// balance should be zero since accounts' balances are expected to be in an escrow account
   752  	balanceX := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomX)
   753  	balanceY := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomY)
   754  	require.Equal(t, sdk.ZeroInt(), balanceX.Amount)
   755  	require.Equal(t, sdk.ZeroInt(), balanceY.Amount)
   756  
   757  	pool, found := simapp.LiquidityKeeper.GetPool(ctx, poolID)
   758  	require.True(t, found)
   759  
   760  	// delete previously created pool
   761  	simapp.LiquidityKeeper.DeletePool(ctx, pool)
   762  
   763  	pool, found = simapp.LiquidityKeeper.GetPool(ctx, poolID)
   764  	require.False(t, found)
   765  
   766  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   767  
   768  	balanceXRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomX)
   769  	balanceYRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomY)
   770  	require.True(sdk.IntEq(t, X, balanceXRefunded.Amount))
   771  	require.True(sdk.IntEq(t, Y, balanceYRefunded.Amount))
   772  
   773  	// next block
   774  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   775  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   776  }
   777  
   778  // This scenario tests refund withdraw scenario
   779  func TestLiquidityScenario5(t *testing.T) {
   780  	simapp, ctx := createTestInput()
   781  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   782  
   783  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   784  
   785  	X := sdk.NewInt(1000000000)
   786  	Y := sdk.NewInt(500000000)
   787  
   788  	// create 20 random accounts with an initial balance of 0.01
   789  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   790  
   791  	// create pool with 1000X and 500Y coins
   792  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   793  
   794  	pool, found := simapp.LiquidityKeeper.GetPool(ctx, poolID)
   795  	require.True(t, found)
   796  
   797  	poolCoin := simapp.BankKeeper.GetBalance(ctx, addrs[0], pool.PoolCoinDenom)
   798  
   799  	// withdraw all pool coin from the pool
   800  	app.TestWithdrawPool(t, simapp, ctx, poolCoin.Amount, addrs[0:1], poolID, false)
   801  
   802  	poolCoinAfter := simapp.BankKeeper.GetBalance(ctx, addrs[0], pool.PoolCoinDenom)
   803  	require.Equal(t, sdk.ZeroInt(), poolCoinAfter.Amount)
   804  
   805  	// save pool coin denom before deleting the pool
   806  	poolCoinDenom := pool.PoolCoinDenom
   807  
   808  	// delete the pool
   809  	simapp.LiquidityKeeper.DeletePool(ctx, pool)
   810  
   811  	pool, found = simapp.LiquidityKeeper.GetPool(ctx, poolID)
   812  	require.False(t, found)
   813  
   814  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   815  
   816  	// pool coin should be refunded since the pool is deleted before executing pool batch
   817  	poolCoinRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[0], poolCoinDenom)
   818  	require.Equal(t, poolCoin.Amount, poolCoinRefunded.Amount)
   819  
   820  	// next block
   821  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   822  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   823  }
   824  
   825  // This scenario tests pool coin and refunded amounts after depositing X and Y amounts of coins
   826  // - 100X and 200Y in reserve pool
   827  // - deposit 30X and 20Y coins
   828  // - test how many pool coins to receive
   829  // - test how many X or Y coins to be refunded
   830  func TestLiquidityScenario6(t *testing.T) {
   831  	simapp, ctx := createTestInput()
   832  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   833  
   834  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   835  
   836  	X := sdk.NewInt(100000000)
   837  	Y := sdk.NewInt(200000000)
   838  
   839  	// create 20 random accounts with an initial balance of 0.01
   840  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   841  
   842  	// create pool with 100X and 200Y coins
   843  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   844  
   845  	pool, found := simapp.LiquidityKeeper.GetPool(ctx, poolID)
   846  	require.True(t, found)
   847  
   848  	poolCoinTotalSupply := simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pool)
   849  
   850  	// use the other account to make deposit to the pool with 30X and 20Y coins
   851  	app.TestDepositPool(t, simapp, ctx, sdk.NewInt(30000000), sdk.NewInt(20000000), addrs[1:2], poolID, false)
   852  
   853  	// execute pool batch
   854  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   855  
   856  	poolCoinBalance := simapp.BankKeeper.GetBalance(ctx, addrs[1], pool.PoolCoinDenom)
   857  	require.Equal(t, sdk.NewInt(100000), poolCoinBalance.Amount)
   858  	require.Equal(t, poolCoinTotalSupply.QuoRaw(10), poolCoinBalance.Amount)
   859  
   860  	balanceXRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomX)
   861  	balanceYRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomY)
   862  	require.Equal(t, sdk.NewInt(20000000), balanceXRefunded.Amount)
   863  	require.Equal(t, sdk.ZeroInt(), balanceYRefunded.Amount)
   864  
   865  	// next block
   866  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   867  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   868  }
   869  
   870  // This scenario is similar with scenario6
   871  // Depositing different amounts will result in different amount of refunded amounts
   872  // - 100X and 200Y in reserve pool
   873  // - deposit 10X and 30Y coins
   874  // - test how many pool coins to receive
   875  // - test how many X or Y coins to be refunded
   876  func TestLiquidityScenario7(t *testing.T) {
   877  	simapp, ctx := createTestInput()
   878  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   879  
   880  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   881  
   882  	X := sdk.NewInt(100000000)
   883  	Y := sdk.NewInt(200000000)
   884  
   885  	// create 20 random accounts with an initial balance of 0.01
   886  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   887  
   888  	// create pool with 100X and 200Y coins
   889  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   890  
   891  	pool, found := simapp.LiquidityKeeper.GetPool(ctx, poolID)
   892  	require.True(t, found)
   893  
   894  	poolCoinTotalSupply := simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pool)
   895  
   896  	// use the other account to make deposit to the pool with 10X and 30Y coins
   897  	app.TestDepositPool(t, simapp, ctx, sdk.NewInt(10000000), sdk.NewInt(30000000), addrs[1:2], poolID, false)
   898  
   899  	// execute pool batch
   900  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   901  
   902  	poolCoinBalance := simapp.BankKeeper.GetBalance(ctx, addrs[1], pool.PoolCoinDenom)
   903  	require.Equal(t, sdk.NewInt(100000), poolCoinBalance.Amount)
   904  	require.Equal(t, poolCoinTotalSupply.QuoRaw(10), poolCoinBalance.Amount)
   905  
   906  	balanceXRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomX)
   907  	balanceYRefunded := simapp.BankKeeper.GetBalance(ctx, addrs[1], denomY)
   908  	require.Equal(t, sdk.ZeroInt(), balanceXRefunded.Amount)
   909  	require.Equal(t, sdk.NewInt(10000000), balanceYRefunded.Amount)
   910  
   911  	// next block
   912  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   913  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   914  }
   915  
   916  // This scenario tests to withdraw amounts from reserve pool to see the impacts of how pool coin and account's balance.
   917  // - 100X and 200Y in reserve pool
   918  // - withdraw 10th of pool coin total supply
   919  // - test pool coin total supply
   920  // - test account's coin balance
   921  func TestLiquidityScenario8(t *testing.T) {
   922  	simapp, ctx := createTestInput()
   923  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
   924  
   925  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   926  
   927  	X := sdk.NewInt(100000000)
   928  	Y := sdk.NewInt(200000000)
   929  
   930  	// create 20 random accounts with an initial balance of 0.01
   931  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   932  
   933  	// create pool with 100X and 200Y coins
   934  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   935  
   936  	pool, found := simapp.LiquidityKeeper.GetPool(ctx, poolID)
   937  	require.True(t, found)
   938  
   939  	poolCoinTotalSupply := simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pool)
   940  
   941  	poolCoinBalance := simapp.BankKeeper.GetBalance(ctx, addrs[0], pool.PoolCoinDenom)
   942  	require.Equal(t, sdk.NewInt(1000000), poolCoinTotalSupply)
   943  	require.Equal(t, sdk.NewInt(1000000), poolCoinBalance.Amount)
   944  
   945  	// withdraw 10th of poolCoinTotalSupply from the pool
   946  	app.TestWithdrawPool(t, simapp, ctx, poolCoinTotalSupply.QuoRaw(10), addrs[0:1], poolID, false)
   947  
   948  	// execute pool batch
   949  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   950  
   951  	poolCoinTotalSupply = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pool)
   952  
   953  	poolCoinBalance = simapp.BankKeeper.GetBalance(ctx, addrs[0], pool.PoolCoinDenom)
   954  	require.Equal(t, sdk.NewInt(900000), poolCoinTotalSupply)
   955  	require.Equal(t, sdk.NewInt(900000), poolCoinBalance.Amount)
   956  
   957  	// next block
   958  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   959  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
   960  }
   961  
   962  // Test UnitBatchHeight when over 1
   963  func TestLiquidityUnitBatchHeight(t *testing.T) {
   964  	simapp, ctx := createTestInput()
   965  	ctx = ctx.WithBlockHeight(1)
   966  
   967  	params := simapp.LiquidityKeeper.GetParams(ctx)
   968  	params.UnitBatchHeight = 2
   969  	simapp.LiquidityKeeper.SetParams(ctx, params)
   970  
   971  	// define test denom X, Y for Liquidity Pool
   972  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
   973  
   974  	X := sdk.NewInt(100000000)
   975  	Y := sdk.NewInt(200000000)
   976  
   977  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
   978  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
   979  
   980  	pool, found := simapp.LiquidityKeeper.GetPool(ctx, poolID)
   981  	require.True(t, found)
   982  	poolCoins := simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pool)
   983  	poolCoinBalance := simapp.BankKeeper.GetBalance(ctx, addrs[0], pool.PoolCoinDenom)
   984  	require.Equal(t, sdk.NewInt(1000000), poolCoins)
   985  	require.Equal(t, sdk.NewInt(1000000), poolCoinBalance.Amount)
   986  	app.TestWithdrawPool(t, simapp, ctx, poolCoins.QuoRaw(10), addrs[0:1], poolID, false)
   987  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
   988  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   989  
   990  	// batch not executed, 1 >= 2(UnitBatchHeight)
   991  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, pool.Id)
   992  	require.True(t, found)
   993  	require.False(t, batch.Executed)
   994  	batchWithdrawMsgs := simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
   995  	require.Equal(t, 1, len(batchWithdrawMsgs))
   996  
   997  	poolCoins = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pool)
   998  	poolCoinBalance = simapp.BankKeeper.GetBalance(ctx, addrs[0], pool.PoolCoinDenom)
   999  	require.Equal(t, sdk.NewInt(1000000), poolCoins)
  1000  	require.Equal(t, sdk.NewInt(900000), poolCoinBalance.Amount)
  1001  
  1002  	// next block
  1003  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1004  	batchWithdrawMsgs = simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
  1005  	require.Equal(t, 1, len(batchWithdrawMsgs))
  1006  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
  1007  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
  1008  
  1009  	// batch executed, 2 >= 2(UnitBatchHeight)
  1010  	batch, found = simapp.LiquidityKeeper.GetPoolBatch(ctx, pool.Id)
  1011  	require.True(t, found)
  1012  	require.True(t, batch.Executed)
  1013  	batchWithdrawMsgs = simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
  1014  	require.Equal(t, 1, len(batchWithdrawMsgs))
  1015  
  1016  	poolCoins = simapp.LiquidityKeeper.GetPoolCoinTotalSupply(ctx, pool)
  1017  	poolCoinBalance = simapp.BankKeeper.GetBalance(ctx, addrs[0], pool.PoolCoinDenom)
  1018  	require.Equal(t, sdk.NewInt(900000), poolCoins)
  1019  	require.Equal(t, sdk.NewInt(900000), poolCoinBalance.Amount)
  1020  
  1021  	// next block
  1022  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1023  
  1024  	// batch msg deleted after batch execution
  1025  	batchWithdrawMsgs = simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
  1026  	require.Equal(t, 0, len(batchWithdrawMsgs))
  1027  }
  1028  
  1029  func TestInitNextBatch(t *testing.T) {
  1030  	simapp, ctx := createTestInput()
  1031  	pool := types.Pool{
  1032  		Id:                    1,
  1033  		TypeId:                1,
  1034  		ReserveCoinDenoms:     nil,
  1035  		ReserveAccountAddress: "",
  1036  		PoolCoinDenom:         "",
  1037  	}
  1038  	simapp.LiquidityKeeper.SetPool(ctx, pool)
  1039  
  1040  	batch := types.NewPoolBatch(pool.Id, 1)
  1041  
  1042  	simapp.LiquidityKeeper.SetPoolBatch(ctx, batch)
  1043  	err := simapp.LiquidityKeeper.InitNextPoolBatch(ctx, batch)
  1044  	require.ErrorIs(t, err, types.ErrBatchNotExecuted)
  1045  
  1046  	batch.Executed = true
  1047  	simapp.LiquidityKeeper.SetPoolBatch(ctx, batch)
  1048  
  1049  	err = simapp.LiquidityKeeper.InitNextPoolBatch(ctx, batch)
  1050  	require.NoError(t, err)
  1051  
  1052  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, batch.PoolId)
  1053  	require.True(t, found)
  1054  	require.False(t, batch.Executed)
  1055  	require.Equal(t, uint64(2), batch.Index)
  1056  
  1057  }
  1058  
  1059  func TestDeleteAndInitPoolBatchDeposit(t *testing.T) {
  1060  	simapp, ctx := createTestInput()
  1061  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
  1062  
  1063  	// define test denom X, Y for Liquidity Pool
  1064  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
  1065  
  1066  	X := sdk.NewInt(1000000000)
  1067  	Y := sdk.NewInt(500000000)
  1068  
  1069  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
  1070  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
  1071  
  1072  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
  1073  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
  1074  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
  1075  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
  1076  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
  1077  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
  1078  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
  1079  
  1080  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
  1081  	require.True(t, found)
  1082  
  1083  	depositsAll := simapp.LiquidityKeeper.GetAllPoolBatchDepositMsgs(ctx, batch)
  1084  	require.Equal(t, 6, len(depositsAll))
  1085  	depositsAll[0].Executed = true
  1086  	depositsAll[0].ToBeDeleted = false
  1087  	simapp.LiquidityKeeper.SetPoolBatchDepositMsgStates(ctx, poolID, depositsAll)
  1088  	depositsRemaining := simapp.LiquidityKeeper.GetAllRemainingPoolBatchDepositMsgStates(ctx, batch)
  1089  	batch.Executed = true
  1090  	simapp.LiquidityKeeper.SetPoolBatch(ctx, batch)
  1091  	simapp.LiquidityKeeper.DeleteAndInitPoolBatches(ctx)
  1092  	depositsAfter := simapp.LiquidityKeeper.GetAllRemainingPoolBatchDepositMsgStates(ctx, batch)
  1093  
  1094  	require.Equal(t, 1, len(depositsRemaining))
  1095  	require.Equal(t, 0, len(depositsAfter))
  1096  
  1097  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
  1098  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1099  }
  1100  
  1101  func TestDeleteAndInitPoolBatchWithdraw(t *testing.T) {
  1102  	simapp, ctx := createTestInput()
  1103  	simapp.LiquidityKeeper.SetParams(ctx, types.DefaultParams())
  1104  
  1105  	// define test denom X, Y for Liquidity Pool
  1106  	denomX, denomY := types.AlphabeticalDenomPair(DenomX, DenomY)
  1107  
  1108  	X := sdk.NewInt(1000000000)
  1109  	Y := sdk.NewInt(500000000)
  1110  
  1111  	addrs := app.AddTestAddrsIncremental(simapp, ctx, 20, sdk.NewInt(10000))
  1112  	poolID := app.TestCreatePool(t, simapp, ctx, X, Y, denomX, denomY, addrs[0])
  1113  
  1114  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
  1115  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
  1116  	app.TestDepositPool(t, simapp, ctx, X.QuoRaw(10), Y, addrs[1:2], poolID, false)
  1117  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
  1118  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
  1119  	app.TestDepositPool(t, simapp, ctx, X, Y.QuoRaw(10), addrs[2:3], poolID, false)
  1120  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
  1121  
  1122  	// next block
  1123  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
  1124  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1125  
  1126  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(5000), addrs[1:2], poolID, false)
  1127  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(500), addrs[1:2], poolID, false)
  1128  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(50), addrs[1:2], poolID, false)
  1129  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(5000), addrs[2:3], poolID, false)
  1130  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(500), addrs[2:3], poolID, false)
  1131  	app.TestWithdrawPool(t, simapp, ctx, sdk.NewInt(50), addrs[2:3], poolID, false)
  1132  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
  1133  
  1134  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, poolID)
  1135  	require.True(t, found)
  1136  
  1137  	withdrawsAll := simapp.LiquidityKeeper.GetAllPoolBatchWithdrawMsgStates(ctx, batch)
  1138  	require.Equal(t, 6, len(withdrawsAll))
  1139  	withdrawsAll[0].Executed = true
  1140  	withdrawsAll[0].ToBeDeleted = false
  1141  	simapp.LiquidityKeeper.SetPoolBatchWithdrawMsgStates(ctx, poolID, withdrawsAll)
  1142  	withdrawsRemaining := simapp.LiquidityKeeper.GetAllRemainingPoolBatchWithdrawMsgStates(ctx, batch)
  1143  	batch.Executed = true
  1144  	simapp.LiquidityKeeper.SetPoolBatch(ctx, batch)
  1145  	simapp.LiquidityKeeper.DeleteAndInitPoolBatches(ctx)
  1146  	withdrawsAfter := simapp.LiquidityKeeper.GetAllRemainingPoolBatchWithdrawMsgStates(ctx, batch)
  1147  	require.Equal(t, 1, len(withdrawsRemaining))
  1148  	require.Equal(t, 0, len(withdrawsAfter))
  1149  
  1150  	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
  1151  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1152  }
  1153  
  1154  func TestUnitBatchHeight(t *testing.T) {
  1155  	for _, unitBatchHeight := range []uint32{1, 2, 3, 5, 9} {
  1156  		simapp, ctx := createTestInput()
  1157  		ctx = ctx.WithBlockHeight(1)
  1158  		params := simapp.LiquidityKeeper.GetParams(ctx)
  1159  		params.UnitBatchHeight = unitBatchHeight
  1160  		simapp.LiquidityKeeper.SetParams(ctx, params)
  1161  
  1162  		X, Y := sdk.NewInt(1000000), sdk.NewInt(1000000)
  1163  		pool, err := createPool(simapp, ctx, X, Y, DenomX, DenomY)
  1164  		require.NoError(t, err)
  1165  
  1166  		johnCoins := sdk.NewCoins(
  1167  			sdk.NewInt64Coin(DenomX, 100000000), sdk.NewInt64Coin(DenomY, 100000000))
  1168  		johnAddr := app.AddRandomTestAddr(simapp, ctx, johnCoins)
  1169  
  1170  		for ; ctx.BlockHeight() <= 100; ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) {
  1171  			liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1172  
  1173  			batch, ok := simapp.LiquidityKeeper.GetPoolBatch(ctx, pool.Id)
  1174  			require.True(t, ok)
  1175  			require.False(t, batch.Executed, "batch should not be executed")
  1176  			require.Equal(
  1177  				t, (ctx.BlockHeight()-1)/int64(unitBatchHeight)*int64(unitBatchHeight)+1, batch.BeginHeight)
  1178  
  1179  			_, err = simapp.LiquidityKeeper.SwapWithinBatch(
  1180  				ctx, types.NewMsgSwapWithinBatch(
  1181  					johnAddr, pool.Id, types.DefaultSwapTypeID,
  1182  					sdk.NewInt64Coin(DenomX, 1000), DenomY, sdk.MustNewDecFromStr("1.1"),
  1183  					params.SwapFeeRate), 0)
  1184  			require.NoError(t, err)
  1185  
  1186  			liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
  1187  
  1188  			batch, ok = simapp.LiquidityKeeper.GetPoolBatch(ctx, pool.Id)
  1189  			require.True(t, ok)
  1190  			if ctx.BlockHeight()%int64(unitBatchHeight) == 0 {
  1191  				require.True(t, batch.Executed, "batch should be executed")
  1192  			} else {
  1193  				require.False(t, batch.Executed, "batch should not be executed")
  1194  			}
  1195  			require.Equal(
  1196  				t, (ctx.BlockHeight()-1)/int64(unitBatchHeight)*int64(unitBatchHeight)+1, batch.BeginHeight)
  1197  		}
  1198  	}
  1199  }
  1200  
  1201  func TestSwapAutoOrderExpiryHeight(t *testing.T) {
  1202  	simapp, ctx, pool, _, err := createTestPool(sdk.NewInt64Coin(DenomX, 1000000), sdk.NewInt64Coin(DenomY, 1000000))
  1203  	require.NoError(t, err)
  1204  	ctx = ctx.WithBlockHeight(1)
  1205  	params := simapp.LiquidityKeeper.GetParams(ctx)
  1206  	params.UnitBatchHeight = 5
  1207  	simapp.LiquidityKeeper.SetParams(ctx, params)
  1208  
  1209  	addr := app.AddRandomTestAddr(simapp, ctx, sdk.NewCoins(sdk.NewInt64Coin(DenomX, 1000000)))
  1210  
  1211  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1212  
  1213  	orderPrice := sdk.MustNewDecFromStr("2")
  1214  	sms, err := simapp.LiquidityKeeper.SwapWithinBatch(
  1215  		ctx,
  1216  		types.NewMsgSwapWithinBatch(
  1217  			addr, pool.Id, types.DefaultSwapTypeID, sdk.NewInt64Coin(DenomX, 100000), DenomY, orderPrice, params.SwapFeeRate),
  1218  		types.CancelOrderLifeSpan)
  1219  	require.NoError(t, err)
  1220  	require.Equal(t, int64(5), sms.OrderExpiryHeight)
  1221  
  1222  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
  1223  
  1224  	ctx = ctx.WithBlockHeight(4)
  1225  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1226  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
  1227  	balances := simapp.BankKeeper.GetAllBalances(ctx, addr)
  1228  	require.True(t, balances.AmountOf(DenomX).Equal(sdk.NewInt(1000000-100150)))
  1229  	require.True(t, balances.AmountOf(DenomY).IsZero())
  1230  	batch, found := simapp.LiquidityKeeper.GetPoolBatch(ctx, pool.Id)
  1231  	require.True(t, found)
  1232  	states := simapp.LiquidityKeeper.GetAllPoolBatchSwapMsgStates(ctx, batch)
  1233  	require.Len(t, states, 1)
  1234  
  1235  	ctx = ctx.WithBlockHeight(5)
  1236  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1237  	liquidity.EndBlocker(ctx, simapp.LiquidityKeeper)
  1238  	balances = simapp.BankKeeper.GetAllBalances(ctx, addr)
  1239  	require.True(t, !balances.AmountOf(DenomY).IsZero()) // Check if swap request has executed
  1240  	ctx = ctx.WithBlockHeight(6)
  1241  	liquidity.BeginBlocker(ctx, simapp.LiquidityKeeper)
  1242  	states = simapp.LiquidityKeeper.GetAllPoolBatchSwapMsgStates(ctx, batch)
  1243  	require.Len(t, states, 0)
  1244  }