github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/dex/keeper/keeper_test.go (about)

     1  //go:build ignore
     2  
     3  package keeper
     4  
     5  import (
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/fibonacci-chain/fbc/x/common"
    10  
    11  	"github.com/stretchr/testify/require"
    12  
    13  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    14  	"github.com/fibonacci-chain/fbc/x/dex/types"
    15  )
    16  
    17  const TestProductNotExist = "product-not-exist"
    18  
    19  func getTestTokenPair() *types.TokenPair {
    20  	addr, err := sdk.AccAddressFromBech32(types.TestTokenPairOwner)
    21  	if err != nil {
    22  		panic(err)
    23  	}
    24  	return &types.TokenPair{
    25  		BaseAssetSymbol:  "testToken",
    26  		QuoteAssetSymbol: common.NativeToken,
    27  		InitPrice:        sdk.MustNewDecFromStr("10.0"),
    28  		MaxPriceDigit:    8,
    29  		MaxQuantityDigit: 8,
    30  		MinQuantity:      sdk.MustNewDecFromStr("0"),
    31  		Owner:            addr,
    32  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(0)),
    33  	}
    34  }
    35  
    36  func TestSaveTokenPair(t *testing.T) {
    37  	common.InitConfig()
    38  	testInput := createTestInputWithBalance(t, 1, 10000)
    39  	ctx := testInput.Ctx
    40  	keeper := testInput.DexKeeper
    41  	tokenPair0 := getTestTokenPair()
    42  
    43  	// SaveTokenPair
    44  	err := keeper.SaveTokenPair(ctx, tokenPair0)
    45  	require.Nil(t, err)
    46  
    47  	maxTokenPairID := keeper.GetMaxTokenPairID(ctx)
    48  	require.Equal(t, uint64(1), maxTokenPairID)
    49  
    50  	// SaveTokenPair with id
    51  	tokenPairId := uint64(100)
    52  	tokenPair1 := getTestTokenPair()
    53  	tokenPair1.ID = tokenPairId
    54  	err = keeper.SaveTokenPair(ctx, tokenPair1)
    55  	require.Nil(t, err)
    56  
    57  	maxTokenPairID = keeper.GetMaxTokenPairID(ctx)
    58  	require.Equal(t, tokenPairId, maxTokenPairID)
    59  
    60  	// SaveTokenPair with smaller id
    61  	tokenPair2 := getTestTokenPair()
    62  	tokenPair2.ID = tokenPairId - 1
    63  	err = keeper.SaveTokenPair(ctx, tokenPair2)
    64  	require.Nil(t, err)
    65  
    66  	maxTokenPairID = keeper.GetMaxTokenPairID(ctx)
    67  	require.Equal(t, tokenPairId, maxTokenPairID)
    68  
    69  }
    70  
    71  func TestGetTokenPair(t *testing.T) {
    72  	common.InitConfig()
    73  	testInput := createTestInputWithBalance(t, 1, 10000)
    74  	ctx := testInput.Ctx
    75  	keeper := testInput.DexKeeper
    76  	tokenPair := getTestTokenPair()
    77  
    78  	// SaveTokenPair
    79  	err := keeper.SaveTokenPair(ctx, tokenPair)
    80  	require.Nil(t, err)
    81  
    82  	// GetTokenPair successful
    83  	product := tokenPair.Name()
    84  	getTokenPair := keeper.GetTokenPair(ctx, product)
    85  	require.Equal(t, getTokenPair, tokenPair)
    86  
    87  	userTokenPairs := keeper.GetUserTokenPairs(ctx, tokenPair.Owner)
    88  	require.EqualValues(t, 1, len(userTokenPairs))
    89  
    90  	// GetTokenPair failed
    91  	getTokenPair = keeper.GetTokenPair(ctx, TestProductNotExist)
    92  	require.Nil(t, getTokenPair)
    93  
    94  	// GetTokenPairs from db
    95  	getTokenPairs := keeper.GetTokenPairs(ctx)
    96  	require.Equal(t, 1, len(getTokenPairs))
    97  
    98  	// GetTokenPairs from cache
    99  	getTokenPairs = keeper.GetTokenPairs(ctx)
   100  	require.Equal(t, 1, len(getTokenPairs))
   101  
   102  	// GetTokenPairFromStore
   103  	getTokenPair = keeper.GetTokenPairFromStore(ctx, product)
   104  	require.Equal(t, getTokenPair, tokenPair)
   105  
   106  }
   107  
   108  func TestDeleteTokenPairByName(t *testing.T) {
   109  	common.InitConfig()
   110  	testInput := createTestInputWithBalance(t, 1, 10000)
   111  	ctx := testInput.Ctx
   112  	keeper := testInput.DexKeeper
   113  	tokenPair := getTestTokenPair()
   114  
   115  	// SaveTokenPair
   116  	err := keeper.SaveTokenPair(ctx, tokenPair)
   117  	require.Nil(t, err)
   118  
   119  	userTokenPairs := keeper.GetUserTokenPairs(ctx, tokenPair.Owner)
   120  	require.EqualValues(t, 1, len(userTokenPairs))
   121  
   122  	// DeleteTokenPairByName successful
   123  	product := tokenPair.Name()
   124  	keeper.DeleteTokenPairByName(ctx, tokenPair.Owner, product)
   125  	getTokenPair := keeper.GetTokenPair(ctx, product)
   126  	require.Nil(t, getTokenPair)
   127  
   128  	userTokenPairs = keeper.GetUserTokenPairs(ctx, tokenPair.Owner)
   129  	require.EqualValues(t, 0, len(userTokenPairs))
   130  }
   131  
   132  func TestUpdateTokenPair(t *testing.T) {
   133  	common.InitConfig()
   134  	testInput := createTestInputWithBalance(t, 1, 10000)
   135  	ctx := testInput.Ctx
   136  	keeper := testInput.DexKeeper
   137  	tokenPair := getTestTokenPair()
   138  
   139  	// SaveTokenPair
   140  	err := keeper.SaveTokenPair(ctx, tokenPair)
   141  	require.Nil(t, err)
   142  
   143  	// UpdateTokenPair successful
   144  	product := tokenPair.Name()
   145  	blockHeight := tokenPair.BlockHeight
   146  	updateTokenPair := tokenPair
   147  	updateTokenPair.BlockHeight = blockHeight + 1
   148  	keeper.UpdateTokenPair(ctx, product, updateTokenPair)
   149  	getTokenPair := keeper.GetTokenPair(ctx, product)
   150  	require.Equal(t, getTokenPair.BlockHeight, blockHeight+1)
   151  }
   152  
   153  func TestDeposit(t *testing.T) {
   154  	common.InitConfig()
   155  	testInput := createTestInputWithBalance(t, 2, 10000)
   156  	ctx := testInput.Ctx
   157  	keeper := testInput.DexKeeper
   158  	tokenPair := getTestTokenPair()
   159  	owner := testInput.TestAddrs[0]
   160  	tokenPair.Owner = owner
   161  	initDeposit := tokenPair.Deposits
   162  
   163  	// SaveTokenPair
   164  	err := keeper.SaveTokenPair(ctx, tokenPair)
   165  	require.Nil(t, err)
   166  
   167  	// Deposit successful
   168  	product := tokenPair.Name()
   169  	amount, err := sdk.ParseDecCoin("30" + sdk.DefaultBondDenom)
   170  	require.Nil(t, err)
   171  	err = keeper.Deposit(ctx, product, owner, amount)
   172  	require.Nil(t, err)
   173  
   174  	getTokenPair := keeper.GetTokenPair(ctx, product)
   175  	require.Equal(t, getTokenPair.Deposits, initDeposit.Add(amount))
   176  
   177  	// Deposit failed because of product not exist
   178  	err = keeper.Deposit(ctx, TestProductNotExist, owner, amount)
   179  	require.NotNil(t, err)
   180  
   181  	// Deposit failed because of owner
   182  	err = keeper.Deposit(ctx, product, testInput.TestAddrs[1], amount)
   183  	require.NotNil(t, err)
   184  
   185  	// Deposit failed because of invalid amount
   186  	amountInvalid, err := sdk.ParseDecCoin("30" + common.TestToken)
   187  	require.Nil(t, err)
   188  	err = keeper.Deposit(ctx, product, owner, amountInvalid)
   189  	require.NotNil(t, err)
   190  }
   191  
   192  func TestWithdraw(t *testing.T) {
   193  	common.InitConfig()
   194  	testInput := createTestInputWithBalance(t, 2, 10000)
   195  	ctx := testInput.Ctx
   196  	keeper := testInput.DexKeeper
   197  	tokenPair := getTestTokenPair()
   198  	owner := testInput.TestAddrs[0]
   199  	tokenPair.Owner = owner
   200  	initDeposit := tokenPair.Deposits
   201  	keeper.SetParams(ctx, *types.DefaultParams())
   202  
   203  	// SaveTokenPair
   204  	err := keeper.SaveTokenPair(ctx, tokenPair)
   205  	require.Nil(t, err)
   206  
   207  	// Deposit successful
   208  	product := tokenPair.Name()
   209  	depositAmount, err := sdk.ParseDecCoin("30" + sdk.DefaultBondDenom)
   210  	require.Nil(t, err)
   211  	err = keeper.Deposit(ctx, product, owner, depositAmount)
   212  	require.Nil(t, err)
   213  
   214  	getTokenPair := keeper.GetTokenPair(ctx, product)
   215  	require.Equal(t, getTokenPair.Deposits, initDeposit.Add(depositAmount))
   216  
   217  	// Withdraw successful
   218  	withdrawAmount, err := sdk.ParseDecCoin("10" + sdk.DefaultBondDenom)
   219  	require.Nil(t, err)
   220  	err = keeper.Withdraw(ctx, product, owner, withdrawAmount)
   221  	require.Nil(t, err)
   222  	getTokenPair = keeper.GetTokenPair(ctx, product)
   223  	require.Equal(t, getTokenPair.Deposits, initDeposit.Add(depositAmount).Sub(withdrawAmount))
   224  
   225  	// Withdraw failed because of product not exist
   226  	err = keeper.Withdraw(ctx, TestProductNotExist, owner, withdrawAmount)
   227  	require.NotNil(t, err)
   228  
   229  	// Withdraw failed because of owner
   230  	err = keeper.Withdraw(ctx, product, testInput.TestAddrs[1], withdrawAmount)
   231  	require.NotNil(t, err)
   232  
   233  	// Deposit failed because of invalid amount
   234  	amountInvalid, err := sdk.ParseDecCoin("10" + common.TestToken)
   235  	require.Nil(t, err)
   236  	err = keeper.Withdraw(ctx, product, owner, amountInvalid)
   237  	require.NotNil(t, err)
   238  
   239  	// Withdraw failed because of deposits not enough
   240  	err = keeper.Withdraw(ctx, product, owner, depositAmount)
   241  	require.NotNil(t, err)
   242  }
   243  
   244  func TestGetTokenPairsOrdered(t *testing.T) {
   245  	testInput := createTestInputWithBalance(t, 1, 10000)
   246  	ctx := testInput.Ctx
   247  	keeper := testInput.DexKeeper
   248  
   249  	tokenPair0 := &types.TokenPair{
   250  		BaseAssetSymbol:  "bToken0",
   251  		QuoteAssetSymbol: common.NativeToken,
   252  		Owner:            testInput.TestAddrs[0],
   253  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(50)),
   254  		BlockHeight:      8,
   255  	}
   256  
   257  	tokenPair1 := &types.TokenPair{
   258  		BaseAssetSymbol:  "bToken1",
   259  		QuoteAssetSymbol: common.NativeToken,
   260  		Owner:            testInput.TestAddrs[0],
   261  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(100)),
   262  		BlockHeight:      10,
   263  	}
   264  
   265  	tokenPair2 := &types.TokenPair{
   266  		BaseAssetSymbol:  "bToken2",
   267  		QuoteAssetSymbol: common.NativeToken,
   268  		Owner:            testInput.TestAddrs[0],
   269  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(50)),
   270  		BlockHeight:      9,
   271  	}
   272  
   273  	tokenPair3 := &types.TokenPair{
   274  		BaseAssetSymbol:  "aToken0",
   275  		QuoteAssetSymbol: common.NativeToken,
   276  		Owner:            testInput.TestAddrs[0],
   277  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(50)),
   278  		BlockHeight:      9,
   279  	}
   280  
   281  	// SaveTokenPair
   282  	err := keeper.SaveTokenPair(ctx, tokenPair0)
   283  	require.Nil(t, err)
   284  	err = keeper.SaveTokenPair(ctx, tokenPair1)
   285  	require.Nil(t, err)
   286  	err = keeper.SaveTokenPair(ctx, tokenPair2)
   287  	require.Nil(t, err)
   288  	err = keeper.SaveTokenPair(ctx, tokenPair3)
   289  	require.Nil(t, err)
   290  
   291  	expectedSortedPairs := types.TokenPairs{tokenPair1, tokenPair0, tokenPair3, tokenPair2}
   292  
   293  	// 1. compare deposit
   294  	// 2. compare block height
   295  	// 3. compare product name
   296  	orderTokenPairs := keeper.GetTokenPairsOrdered(ctx)
   297  	for idx, tokenPair := range orderTokenPairs {
   298  		require.Equal(t, expectedSortedPairs[idx].Name(), tokenPair.Name())
   299  	}
   300  }
   301  
   302  func TestSortProducts(t *testing.T) {
   303  	testInput := createTestInputWithBalance(t, 1, 10000)
   304  	ctx := testInput.Ctx
   305  	keeper := testInput.DexKeeper
   306  
   307  	tokenPair0 := &types.TokenPair{
   308  		BaseAssetSymbol:  "bToken0",
   309  		QuoteAssetSymbol: common.NativeToken,
   310  		Owner:            testInput.TestAddrs[0],
   311  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(50)),
   312  		BlockHeight:      8,
   313  	}
   314  
   315  	tokenPair1 := &types.TokenPair{
   316  		BaseAssetSymbol:  "bToken1",
   317  		QuoteAssetSymbol: common.NativeToken,
   318  		Owner:            testInput.TestAddrs[0],
   319  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(100)),
   320  		BlockHeight:      10,
   321  	}
   322  
   323  	tokenPair2 := &types.TokenPair{
   324  		BaseAssetSymbol:  "bToken2",
   325  		QuoteAssetSymbol: common.NativeToken,
   326  		Owner:            testInput.TestAddrs[0],
   327  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(50)),
   328  		BlockHeight:      9,
   329  	}
   330  
   331  	tokenPair3 := &types.TokenPair{
   332  		BaseAssetSymbol:  "aToken0",
   333  		QuoteAssetSymbol: common.NativeToken,
   334  		Owner:            testInput.TestAddrs[0],
   335  		Deposits:         sdk.NewDecCoin(sdk.DefaultBondDenom, sdk.NewInt(50)),
   336  		BlockHeight:      9,
   337  	}
   338  
   339  	// SaveTokenPair
   340  	err := keeper.SaveTokenPair(ctx, tokenPair0)
   341  	require.Nil(t, err)
   342  	err = keeper.SaveTokenPair(ctx, tokenPair1)
   343  	require.Nil(t, err)
   344  	err = keeper.SaveTokenPair(ctx, tokenPair2)
   345  	require.Nil(t, err)
   346  	err = keeper.SaveTokenPair(ctx, tokenPair3)
   347  	require.Nil(t, err)
   348  
   349  	unsoreProducts := []string{tokenPair0.Name(), tokenPair1.Name(), tokenPair2.Name(), tokenPair3.Name()}
   350  	expectedSortedProducts := []string{tokenPair1.Name(), tokenPair0.Name(), tokenPair3.Name(), tokenPair2.Name()}
   351  
   352  	// 1. compare deposit
   353  	// 2. compare block height
   354  	// 3. compare product name
   355  	keeper.SortProducts(ctx, unsoreProducts)
   356  	require.Equal(t, expectedSortedProducts, unsoreProducts)
   357  }
   358  
   359  func Test_IterateWithdrawInfo(t *testing.T) {
   360  	testInput := createTestInputWithBalance(t, 2, 30)
   361  	ctx := testInput.Ctx
   362  	keeper := testInput.DexKeeper
   363  	owner := testInput.TestAddrs[0]
   364  	keeper.SetParams(ctx, *types.DefaultParams())
   365  
   366  	withdrawAmount, err := sdk.ParseDecCoin("10" + sdk.DefaultBondDenom)
   367  	require.Nil(t, err)
   368  	withdrawInfo := types.WithdrawInfo{
   369  		Owner:        owner,
   370  		Deposits:     withdrawAmount,
   371  		CompleteTime: time.Now().Add(types.DefaultWithdrawPeriod),
   372  	}
   373  	keeper.SetWithdrawInfo(ctx, withdrawInfo)
   374  	expectWithdrawInfo, ok := keeper.GetWithdrawInfo(ctx, withdrawInfo.Owner)
   375  	require.True(t, ok)
   376  	require.True(t, withdrawInfo.Equal(expectWithdrawInfo))
   377  
   378  	withdrawInfo.CompleteTime = withdrawInfo.CompleteTime.Add(types.DefaultWithdrawPeriod)
   379  	keeper.SetWithdrawInfo(ctx, withdrawInfo)
   380  	expectWithdrawInfo, ok = keeper.GetWithdrawInfo(ctx, withdrawInfo.Owner)
   381  	require.True(t, ok)
   382  	require.True(t, withdrawInfo.Equal(expectWithdrawInfo))
   383  
   384  	var expectWithdrawInfos types.WithdrawInfos
   385  	keeper.IterateWithdrawInfo(ctx, func(_ int64, withdrawInfo types.WithdrawInfo) (stop bool) {
   386  		expectWithdrawInfos = append(expectWithdrawInfos, withdrawInfo)
   387  		return false
   388  	})
   389  	require.Equal(t, 1, len(expectWithdrawInfos))
   390  	require.True(t, expectWithdrawInfos[0].Equal(expectWithdrawInfo))
   391  }
   392  
   393  func TestKeeper_CheckTokenPairUnderDexDelist(t *testing.T) {
   394  	testInput := createTestInputWithBalance(t, 2, 30)
   395  
   396  	// fail case : the product is not exist
   397  	isDelisting, err := testInput.DexKeeper.CheckTokenPairUnderDexDelist(testInput.Ctx, "no-product")
   398  	require.Error(t, err)
   399  	require.True(t, isDelisting)
   400  
   401  	// save token pair
   402  	tokenPair := getTestTokenPair()
   403  	err = testInput.DexKeeper.SaveTokenPair(testInput.Ctx, tokenPair)
   404  	require.Nil(t, err)
   405  
   406  	// successful case
   407  	isDelisting, err = testInput.DexKeeper.CheckTokenPairUnderDexDelist(testInput.Ctx, tokenPair.Name())
   408  	require.Nil(t, err)
   409  	require.Equal(t, isDelisting, tokenPair.Delisting)
   410  
   411  }