From da4d9d5dd959991d042b75f66b7aa9b37a772d50 Mon Sep 17 00:00:00 2001 From: Anh Minh <1phamminh0811@gmail.com> Date: Sat, 27 Jul 2024 20:35:47 +0700 Subject: [PATCH] Add test for fee tax non value token denom --- tests/e2e/configurer/chain/commands.go | 12 +++++- tests/e2e/containers/containers.go | 4 +- tests/e2e/e2e_test.go | 53 ++++++++++++++++++++++++++ tests/e2e/initialization/config.go | 16 ++++---- x/tax2gas/README.md | 2 + 5 files changed, 76 insertions(+), 11 deletions(-) diff --git a/tests/e2e/configurer/chain/commands.go b/tests/e2e/configurer/chain/commands.go index 146b3be6..93d098d9 100644 --- a/tests/e2e/configurer/chain/commands.go +++ b/tests/e2e/configurer/chain/commands.go @@ -82,9 +82,9 @@ func (n *NodeConfig) WasmExecuteError(contract, execMsg, amount, from string, ga } cmd = append(cmd, "--gas", gasLimit, "--fees", fees.String()) n.LogActionF(strings.Join(cmd, " ")) - _, _, err := n.containerManager.ExecTxCmdError(n.t, n.chainID, n.Name, cmd) + _, _, err := n.containerManager.ExecTxCmdError(n.t, n.chainID, n.Name, cmd, "", true) require.NoError(n.t, err) - n.LogActionF("successfully executed") + n.LogActionF("executed failed") } // QueryParams extracts the params for a given subspace and key. This is done generically via json to avoid having to @@ -223,6 +223,14 @@ func extractProposalIDFromResponse(response string) (int, error) { return proposalID, nil } +func (n *NodeConfig) BankSendError(amount string, sendAddress string, receiveAddress string, walletName string, gasLimit string, fees sdk.Coins, failError string) { + n.LogActionF("bank sending %s from address %s to %s", amount, sendAddress, receiveAddress) + cmd := []string{"terrad", "tx", "bank", "send", sendAddress, receiveAddress, amount, fmt.Sprintf("--from=%s", walletName)} + cmd = append(cmd, "--fees", fees.String(), "--gas", gasLimit) + _, _, err := n.containerManager.ExecTxCmdError(n.t, n.chainID, n.Name, cmd, failError, false) + require.NoError(n.t, err) + n.LogActionF("failed sent bank sent %s from address %s to %s", amount, sendAddress, receiveAddress) +} func (n *NodeConfig) BankSend(amount string, sendAddress string, receiveAddress string, gasLimit string, fees sdk.Coins) { n.BankSendWithWallet(amount, sendAddress, receiveAddress, "val", gasLimit, fees) } diff --git a/tests/e2e/containers/containers.go b/tests/e2e/containers/containers.go index b5c53ca0..6cd0e854 100644 --- a/tests/e2e/containers/containers.go +++ b/tests/e2e/containers/containers.go @@ -84,7 +84,7 @@ func (m *Manager) ExecTxCmd(t *testing.T, chainID string, containerName string, } // ExecTxCmdError Runs ExecCmd -func (m *Manager) ExecTxCmdError(t *testing.T, chainID string, containerName string, command []string) (bytes.Buffer, bytes.Buffer, error) { +func (m *Manager) ExecTxCmdError(t *testing.T, chainID string, containerName string, command []string, failStr string, checkTxHash bool) (bytes.Buffer, bytes.Buffer, error) { allTxArgs := []string{fmt.Sprintf("--chain-id=%s", chainID), "--yes", "--keyring-backend=test", "--log_format=json"} // parse to see if command has gas flags. If not, add default gas flags. addGasFlags := true @@ -97,7 +97,7 @@ func (m *Manager) ExecTxCmdError(t *testing.T, chainID string, containerName str allTxArgs = append(allTxArgs, txDefaultGasArgs...) } txCommand := append(command, allTxArgs...) //nolint - return m.ExecCmd(t, containerName, txCommand, "", true) + return m.ExecCmd(t, containerName, txCommand, failStr, checkTxHash) } // ExecTxCmdWithSuccessString Runs ExecCmd, with flags for txs added. diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index 1f7957b0..8132ce40 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -527,3 +527,56 @@ func (s *IntegrationTestSuite) TestFeeTaxForwardWasm() { // Transfer amount will we return s.Require().Equal(newTest1AddrBalance.Amount, test1AddrBalance.Amount) } + +func (s *IntegrationTestSuite) TestFeeTaxNotAcceptDenom() { + chain := s.configurer.GetChainConfig(0) + node, err := chain.GetDefaultNode() + s.Require().NoError(err) + + transferAmount1 := sdkmath.NewInt(500000000) + transferCoin1TerraDenom := sdk.NewCoin(initialization.TerraDenom, transferAmount1) + transferCoin1NonValueDenom := sdk.NewCoin(initialization.NonValueDenom, transferAmount1) + + test1Addr := node.CreateWallet("test1-not-accept-denom") + test2Addr := node.CreateWallet("test2-not-accept-denom") + + validatorAddr := node.GetWallet(initialization.ValidatorWalletName) + + gasLimit := transferAmount1.MulRaw(initialization.E10).String() + node.BankSend(transferCoin1TerraDenom.String(), validatorAddr, test1Addr, gasLimit, sdk.NewCoins(transferCoin1TerraDenom)) + + gasLimit = "200000" + fees := sdk.NewCoins(sdk.NewCoin(initialization.TerraDenom, sdkmath.NewInt(10))) + node.BankSend(transferCoin1NonValueDenom.String(), validatorAddr, test1Addr, gasLimit, fees) + + // Test 1: Try to pay tx fee with non-value denom + transferAmount2 := sdkmath.NewInt(100000000) + transferCoin2 := sdk.NewCoin(initialization.TerraDenom, transferAmount2) + + gasLimit = transferAmount2.MulRaw(initialization.E10).String() + fees = sdk.NewCoins(sdk.NewCoin(initialization.NonValueDenom, transferAmount2)) + err = fmt.Errorf("insufficient fees") + // Tx will cause error cause it doesn't have the correct fees to pay for tx + node.BankSendError(transferCoin2.String(), test1Addr, test2Addr, "test1-not-accept-denom", gasLimit, fees, err.Error()) + + // Test 2: Try to trick the chain by paying with both uluna and non-value denom + + // Use the uluna amount that is smaller than the tax + feeAmount := transferAmount2 + feeTerraCoin := sdk.NewCoin(initialization.TerraDenom, feeAmount) + gasLimit = transferAmount2.MulRaw(initialization.E10).String() + fees = sdk.NewCoins(sdk.NewCoin(initialization.NonValueDenom, transferAmount2), feeTerraCoin) + + // At this time, the tx will ignore non-value denom and only deduct the uluna + node.BankSendWithWallet(transferCoin2.String(), test1Addr, test2Addr, "test1-not-accept-denom", gasLimit, fees) + + balanceTest1Terra, err := node.QuerySpecificBalance(test1Addr, initialization.TerraDenom) + s.Require().NoError(err) + balanceTest1NonValueDenom, err := node.QuerySpecificBalance(test1Addr, initialization.NonValueDenom) + s.Require().NoError(err) + + fee := initialization.TaxRate.MulInt(transferAmount2).TruncateInt().AddRaw(2) + s.Require().Equal(balanceTest1Terra.Amount, transferAmount1.Sub(transferAmount2).Sub(fee)) + s.Require().Equal(balanceTest1NonValueDenom, transferCoin1NonValueDenom) + +} diff --git a/tests/e2e/initialization/config.go b/tests/e2e/initialization/config.go index 5532c69d..7be49662 100644 --- a/tests/e2e/initialization/config.go +++ b/tests/e2e/initialization/config.go @@ -46,18 +46,20 @@ const ( TerraDenom = "uluna" UsdDenom = "uusd" EurDenom = "ueur" + NonValueDenom = "nonvalue" TerraIBCDenom = "ibc/4627AD2524E3E0523047E35BB76CC90E37D9D57ACF14F0FCBCEB2480705F3CB8" MinGasPrice = "0.00000000001" E10 = 10000000000 IbcSendAmount = 3300000000 ValidatorWalletName = "val" // chainA - ChainAID = "terra-test-a" - TerraBalanceA = 20000000000000 - UsdBalanceA = 30000000000000 - EurBalanceA = 40000000000000 - StakeBalanceA = 110000000000 - StakeAmountA = 100000000000 + ChainAID = "terra-test-a" + TerraBalanceA = 200000000000000 + UsdBalanceA = 300000000000000 + EurBalanceA = 400000000000000 + NonValueBalanceA = 10000000000000 + StakeBalanceA = 110000000000 + StakeAmountA = 100000000000 // chainB ChainBID = "terra-test-b" TerraBalanceB = 500000000000 @@ -80,7 +82,7 @@ var ( StakeAmountIntB = sdk.NewInt(StakeAmountB) StakeAmountCoinB = sdk.NewCoin(TerraDenom, StakeAmountIntB) - InitBalanceStrA = fmt.Sprintf("%d%s,%d%s,%d%s", TerraBalanceA, TerraDenom, UsdBalanceA, UsdDenom, EurBalanceA, EurDenom) + InitBalanceStrA = fmt.Sprintf("%d%s,%d%s,%d%s,%d%s", TerraBalanceA, TerraDenom, UsdBalanceA, UsdDenom, EurBalanceA, EurDenom, NonValueBalanceA, NonValueDenom) InitBalanceStrB = fmt.Sprintf("%d%s,%d%s,%d%s", TerraBalanceB, TerraDenom, UsdBalanceB, UsdDenom, EurBalanceB, EurDenom) // InitBalanceStrC = fmt.Sprintf("%d%s", TerraBalanceC, TerraDenom) LunaToken = sdk.NewInt64Coin(TerraDenom, IbcSendAmount) // 3,300luna diff --git a/x/tax2gas/README.md b/x/tax2gas/README.md index f5a01c4d..3fcd0478 100644 --- a/x/tax2gas/README.md +++ b/x/tax2gas/README.md @@ -11,6 +11,7 @@ - Out of gas should return the tax and not consumed gas - Grant msg should work - Allow pay with multiple fees should work +- Try to pay with non value token denom should fail | No | Name | Scenario | Expect Result | Covered by | |----|----------|-------------------|---------------|------------| @@ -23,3 +24,4 @@ | 7 | Out of gas should return the tax and not consumed gas | User make some transactions with limited gas amount that will lead to cause `out of gas` error | Tax and not consumed gas should be revert to user | 🛑 Not figure out the way to make `out of gas` error occur, should be test in testnet | | 8 | Grant msg should work | User grant multiple type of permissions to different transactions | Grant permission msg will only can deduct one denom in ante handler and one denom in post hanlder | [TestFeeTaxGrant](../../tests/e2e/e2e_test.go#L214) | | 9 | Allow pay with multiple fees should work | User make transaction with multiple coins as fee | Fee can be paid by multiple denom, if one denom is not enough, then it will deduct other denom | [TestFeeTaxMultipleDenoms](../../tests/e2e/e2e_test.go#L380) | +| 10 | Try to pay with non value token denom should fail | User make transaction that use a different denom as fee | That denom should be reject and the tx should only accept denom listed in params | [TestFeeTaxNotAcceptDenom](../../tests/e2e/e2e_test.go#L531) | \ No newline at end of file