Skip to content

Commit

Permalink
Merge branch 'minh/tax2gas' of github-expertdicer:classic-terra/core …
Browse files Browse the repository at this point in the history
…into minh/tax2gas
  • Loading branch information
expertdicer committed Jul 24, 2024
2 parents 1327e9d + 56ea70b commit 644d5f4
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 83 deletions.
44 changes: 20 additions & 24 deletions tests/e2e/configurer/chain/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,19 @@ import (

func (n *NodeConfig) StoreWasmCode(wasmFile, from string) {
n.LogActionF("storing wasm code from file %s", wasmFile)
cmd := []string{"terrad", "tx", "wasm", "store", wasmFile, fmt.Sprintf("--from=%s", from)}
cmd := []string{"terrad", "tx", "wasm", "store", wasmFile, fmt.Sprintf("--from=%s", from), "--fees=10uluna", "--gas=2000000"}
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully stored")
}

func (n *NodeConfig) InstantiateWasmContract(codeID, initMsg, amount, from string) {
func (n *NodeConfig) InstantiateWasmContract(codeID, initMsg, amount, from string, gasLimit string, fees sdk.Coins) {
n.LogActionF("instantiating wasm contract %s with %s", codeID, initMsg)
cmd := []string{"terrad", "tx", "wasm", "instantiate", codeID, initMsg, fmt.Sprintf("--from=%s", from), "--no-admin", "--label=ratelimit"}
if amount != "" {
cmd = append(cmd, fmt.Sprintf("--amount=%s", amount))
}
cmd = append(cmd, "--gas", gasLimit, "--fees", fees.String())
n.LogActionF(strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)

Expand All @@ -45,35 +46,28 @@ func (n *NodeConfig) InstantiateWasmContract(codeID, initMsg, amount, from strin
n.LogActionF("successfully initialized")
}

func (n *NodeConfig) Instantiate2WasmContract(codeID, initMsg, salt, amount, fee, gas, from string) {
func (n *NodeConfig) Instantiate2WasmContract(codeID, initMsg, salt, amount, from string, gasLimit string, fees sdk.Coins) {
n.LogActionF("instantiating wasm contract %s with %s", codeID, initMsg)
encodedSalt := make([]byte, hex.EncodedLen(len([]byte(salt))))
hex.Encode(encodedSalt, []byte(salt))
cmd := []string{"terrad", "tx", "wasm", "instantiate2", codeID, initMsg, string(encodedSalt), fmt.Sprintf("--from=%s", from), "--no-admin", "--label=ratelimit"}
if amount != "" {
cmd = append(cmd, fmt.Sprintf("--amount=%s", amount))
}
if fee != "" {
cmd = append(cmd, fmt.Sprintf("--fees=%s", fee))
}
if gas != "" {
cmd = append(cmd, fmt.Sprintf("--gas=%s", gas))
}
cmd = append(cmd, "--gas", gasLimit, "--fees", fees.String())
n.LogActionF(strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully initialized")
}

func (n *NodeConfig) WasmExecute(contract, execMsg, amount, fee, from string) {
func (n *NodeConfig) WasmExecute(contract, execMsg, amount, from string, gasLimit string, fees sdk.Coins) {
n.LogActionF("executing %s on wasm contract %s from %s", execMsg, contract, from)
cmd := []string{"terrad", "tx", "wasm", "execute", contract, execMsg, fmt.Sprintf("--from=%s", from)}
if amount != "" {
cmd = append(cmd, fmt.Sprintf("--amount=%s", amount))
}
if fee != "" {
cmd = append(cmd, fmt.Sprintf("--fees=%s", fee))
}
cmd = append(cmd, "--gas", gasLimit, "--fees", fees.String())
n.LogActionF(strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)
Expand Down Expand Up @@ -124,6 +118,7 @@ func (n *NodeConfig) SubmitAddBurnTaxExemptionAddressProposal(addresses []string
"add-burn-tax-exemption-address", strings.Join(addresses, ","),
"--title=\"burn tax exemption address\"",
"--description=\"\"burn tax exemption address",
"--gas", "300000", "--gas-prices", "1uluna",
fmt.Sprintf("--from=%s", walletName),
}

Expand Down Expand Up @@ -152,7 +147,7 @@ func (n *NodeConfig) FailIBCTransfer(from, recipient, amount string) {
func (n *NodeConfig) SendIBCTransfer(from, recipient, amount, memo string) {
n.LogActionF("IBC sending %s from %s to %s. memo: %s", amount, from, recipient, memo)

cmd := []string{"terrad", "tx", "ibc-transfer", "transfer", "transfer", "channel-0", recipient, amount, fmt.Sprintf("--from=%s", from), "--memo", memo}
cmd := []string{"terrad", "tx", "ibc-transfer", "transfer", "transfer", "channel-0", recipient, amount, fmt.Sprintf("--from=%s", from), "--memo", memo, "--fees=10uluna"}

_, _, err := n.containerManager.ExecTxCmdWithSuccessString(n.t, n.chainID, n.Name, cmd, "\"code\":0")
require.NoError(n.t, err)
Expand All @@ -171,15 +166,15 @@ func (n *NodeConfig) SubmitTextProposal(text string, initialDeposit sdk.Coin) {
func (n *NodeConfig) DepositProposal(proposalNumber int) {
n.LogActionF("depositing on proposal: %d", proposalNumber)
deposit := sdk.NewCoin(initialization.TerraDenom, sdk.NewInt(20*assets.MicroUnit)).String()
cmd := []string{"terrad", "tx", "gov", "deposit", fmt.Sprintf("%d", proposalNumber), deposit, "--from=val"}
cmd := []string{"terrad", "tx", "gov", "deposit", fmt.Sprintf("%d", proposalNumber), deposit, "--from=val", "--gas", "300000", "--fees", "10000000uluna"}
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully deposited on proposal %d", proposalNumber)
}

func (n *NodeConfig) VoteYesProposal(from string, proposalNumber int) {
n.LogActionF("voting yes on proposal: %d", proposalNumber)
cmd := []string{"terrad", "tx", "gov", "vote", fmt.Sprintf("%d", proposalNumber), "yes", fmt.Sprintf("--from=%s", from)}
cmd := []string{"terrad", "tx", "gov", "vote", fmt.Sprintf("%d", proposalNumber), "yes", fmt.Sprintf("--from=%s", from), "--gas", "300000", "--fees", "10000000uluna"}
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully voted yes on proposal %d", proposalNumber)
Expand Down Expand Up @@ -216,44 +211,45 @@ func extractProposalIDFromResponse(response string) (int, error) {
return proposalID, nil
}

func (n *NodeConfig) BankSend(amount string, sendAddress string, receiveAddress string) {
n.BankSendWithWallet(amount, sendAddress, receiveAddress, "val")
func (n *NodeConfig) BankSend(amount string, sendAddress string, receiveAddress string, gasLimit string, fees sdk.Coins) {
n.BankSendWithWallet(amount, sendAddress, receiveAddress, "val", gasLimit, fees)
}

func (n *NodeConfig) BankSendWithWallet(amount string, sendAddress string, receiveAddress string, walletName string) {
func (n *NodeConfig) BankSendWithWallet(amount string, sendAddress string, receiveAddress string, walletName string, gasLimit string, fees sdk.Coins) {
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.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully sent bank sent %s from address %s to %s", amount, sendAddress, receiveAddress)
}

func (n *NodeConfig) BankSendFeeGrantWithWallet(amount string, sendAddress string, receiveAddress string, feeGranter string, walletName string) {
func (n *NodeConfig) BankSendFeeGrantWithWallet(amount string, sendAddress string, receiveAddress string, feeGranter string, walletName string, gasLimit string, fees sdk.Coins) {
n.LogActionF("bank sending %s from address %s to %s", amount, sendAddress, receiveAddress)
cmd := []string{"terrad", "tx", "bank", "send", sendAddress, receiveAddress, amount, fmt.Sprintf("--fee-granter=%s", feeGranter), fmt.Sprintf("--from=%s", walletName)}
cmd = append(cmd, "--fees", fees.String(), "--gas", gasLimit)
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)

n.LogActionF("successfully sent bank sent %s from address %s to %s", amount, sendAddress, receiveAddress)
}

func (n *NodeConfig) BankMultiSend(amount string, split bool, sendAddress string, receiveAddresses ...string) {
func (n *NodeConfig) BankMultiSend(amount string, split bool, sendAddress string, gasLimit string, fees sdk.Coins, receiveAddresses ...string) {
n.LogActionF("bank multisending from %s to %s", sendAddress, strings.Join(receiveAddresses, ","))
cmd := []string{"terrad", "tx", "bank", "multi-send", sendAddress}
cmd = append(cmd, receiveAddresses...)
cmd = append(cmd, amount, "--from=val")
cmd = append(cmd, amount, "--from=val", "--fees", fees.String(), "--gas", gasLimit)
if split {
cmd = append(cmd, "--split")
}

_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully multisent %s to %s", sendAddress, strings.Join(receiveAddresses, ","))
}

func (n *NodeConfig) GrantAddress(granter, gratee string, spendLimit string, walletName string) {
n.LogActionF("granting for address %s", gratee)
cmd := []string{"terrad", "tx", "feegrant", "grant", granter, gratee, fmt.Sprintf("--from=%s", walletName), fmt.Sprintf("--spend-limit=%s", spendLimit)}
cmd := []string{"terrad", "tx", "feegrant", "grant", granter, gratee, fmt.Sprintf("--from=%s", walletName), fmt.Sprintf("--spend-limit=%s", spendLimit), "--fees=10uluna"}
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainID, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully granted for address %s", gratee)
Expand Down
114 changes: 68 additions & 46 deletions tests/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func (s *IntegrationTestSuite) TestIBCWasmHooks() {
nodeA.InstantiateWasmContract(
strconv.Itoa(chainA.LatestCodeID),
`{"count": "0"}`, "",
initialization.ValidatorWalletName)
initialization.ValidatorWalletName, "200000", sdk.NewCoins(sdk.NewCoin(initialization.TerraDenom, sdk.NewInt(10))))

contracts, err := nodeA.QueryContractsFromID(chainA.LatestCodeID)
s.NoError(err)
Expand Down Expand Up @@ -104,6 +104,7 @@ func (s *IntegrationTestSuite) TestAddBurnTaxExemptionAddress() {
s.Require().Contains(whitelistedAddresses, whitelistAddr2)
}

// Each tx gas will cost 2 uluna (1 is for ante handler, 1 is for post handler)
func (s *IntegrationTestSuite) TestFeeTax() {
chain := s.configurer.GetChainConfig(0)
node, err := chain.GetDefaultNode()
Expand All @@ -119,14 +120,16 @@ func (s *IntegrationTestSuite) TestFeeTax() {
s.Require().NoError(err)

test1Addr := node.CreateWallet("test1")
test2Addr := node.CreateWallet("test2")

// Test 1: banktypes.MsgSend
// burn tax with bank send
node.BankSend(transferCoin1.String(), validatorAddr, test1Addr)

subAmount := transferAmount1.Add(initialization.TaxRate.MulInt(transferAmount1).TruncateInt())

decremented := validatorBalance.Sub(sdk.NewCoin(initialization.TerraDenom, subAmount))
gasLimit := transferCoin1.Amount.MulRaw(initialization.E10).String()
node.BankSend(transferCoin1.String(), validatorAddr, test1Addr, gasLimit, sdk.NewCoins(transferCoin1))

decremented := validatorBalance.Sub(sdk.NewCoin(initialization.TerraDenom, subAmount.AddRaw(2)))
newValidatorBalance, err := node.QuerySpecificBalance(validatorAddr, initialization.TerraDenom)
s.Require().NoError(err)

Expand All @@ -136,46 +139,22 @@ func (s *IntegrationTestSuite) TestFeeTax() {
s.Require().Equal(balanceTest1.Amount, transferAmount1)
s.Require().Equal(newValidatorBalance, decremented)

// Test 2: try bank send with grant
test2Addr := node.CreateWallet("test2")
transferAmount2 := sdkmath.NewInt(10000000)
transferCoin2 := sdk.NewCoin(initialization.TerraDenom, transferAmount2)

node.BankSend(transferCoin2.String(), validatorAddr, test2Addr)
node.GrantAddress(test2Addr, test1Addr, transferCoin2.String(), "test2")

// Test 2: banktypes.MsgMultiSend
validatorBalance, err = node.QuerySpecificBalance(validatorAddr, initialization.TerraDenom)
s.Require().NoError(err)

node.BankSendFeeGrantWithWallet(transferCoin2.String(), test1Addr, validatorAddr, test2Addr, "test1")

newValidatorBalance, err = node.QuerySpecificBalance(validatorAddr, initialization.TerraDenom)
s.Require().NoError(err)

balanceTest1, err = node.QuerySpecificBalance(test1Addr, initialization.TerraDenom)
s.Require().NoError(err)

balanceTest2, err := node.QuerySpecificBalance(test2Addr, initialization.TerraDenom)
s.Require().NoError(err)

s.Require().Equal(balanceTest1.Amount, transferAmount1.Sub(transferAmount2))
s.Require().Equal(newValidatorBalance, validatorBalance.Add(transferCoin2))
s.Require().Equal(balanceTest2.Amount, transferAmount2.Sub(initialization.TaxRate.MulInt(transferAmount2).TruncateInt()))

// Test 3: banktypes.MsgMultiSend
validatorBalance, err = node.QuerySpecificBalance(validatorAddr, initialization.TerraDenom)
s.Require().NoError(err)

node.BankMultiSend(transferCoin1.String(), false, validatorAddr, test1Addr, test2Addr)
totalTransferAmount := transferAmount1.Mul(sdk.NewInt(2))
gasLimit = transferCoin1.Amount.MulRaw(initialization.E10).String()
node.BankMultiSend(transferCoin1.String(), false, validatorAddr, gasLimit, sdk.NewCoins(transferCoin1), test1Addr, test2Addr)

newValidatorBalance, err = node.QuerySpecificBalance(validatorAddr, initialization.TerraDenom)
s.Require().NoError(err)

totalTransferAmount := transferAmount1.Mul(sdk.NewInt(2))
subAmount = totalTransferAmount.Add(initialization.TaxRate.MulInt(totalTransferAmount).TruncateInt())
s.Require().Equal(newValidatorBalance, validatorBalance.Sub(sdk.NewCoin(initialization.TerraDenom, subAmount)))
s.Require().Equal(newValidatorBalance, validatorBalance.Sub(sdk.NewCoin(initialization.TerraDenom, subAmount.AddRaw(2))))
}

// Each tx gas will cost 2 uluna (1 is for ante handler, 1 is for post handler)
func (s *IntegrationTestSuite) TestFeeTaxWasm() {
chain := s.configurer.GetChainConfig(0)
node, err := chain.GetDefaultNode()
Expand All @@ -184,49 +163,92 @@ func (s *IntegrationTestSuite) TestFeeTaxWasm() {
testAddr := node.CreateWallet("test")
transferAmount := sdkmath.NewInt(100000000)
transferCoin := sdk.NewCoin(initialization.TerraDenom, transferAmount)
node.BankSend(fmt.Sprintf("%suluna", transferAmount.Mul(sdk.NewInt(4))), initialization.ValidatorWalletName, testAddr)

gasLimit := transferCoin.Amount.MulRaw(initialization.E10).String()
node.BankSend(fmt.Sprintf("%suluna", transferAmount.Mul(sdk.NewInt(4))), initialization.ValidatorWalletName, testAddr, gasLimit, sdk.NewCoins(transferCoin))
node.StoreWasmCode("counter.wasm", initialization.ValidatorWalletName)
chain.LatestCodeID = int(node.QueryLatestWasmCodeID())
// instantiate contract and transfer 100000000uluna
node.InstantiateWasmContract(
strconv.Itoa(chain.LatestCodeID),
`{"count": "0"}`, transferCoin.String(),
"test")
"test", gasLimit, sdk.NewCoins(transferCoin))

contracts, err := node.QueryContractsFromID(chain.LatestCodeID)
s.Require().NoError(err)
s.Require().Len(contracts, 1, "Wrong number of contracts for the counter")

balance1, err := node.QuerySpecificBalance(testAddr, initialization.TerraDenom)
s.Require().NoError(err)
// 400000000 - 100000000 - 100000000 * TaxRate = 300000000 - 10000000 * TaxRate
// 400000000 - 100000000 - 100000000 * TaxRate - 2 (gas) = 300000000 - 10000000 * TaxRate - 2 (gas)
taxAmount := initialization.TaxRate.MulInt(transferAmount).TruncateInt()
s.Require().Equal(balance1.Amount, transferAmount.Mul(sdk.NewInt(3)).Sub(taxAmount))

stabilityFee := sdk.NewDecWithPrec(2, 2).MulInt(transferAmount)
s.Require().Equal(balance1.Amount, transferAmount.Mul(sdk.NewInt(3)).Sub(taxAmount).SubRaw(2))

node.Instantiate2WasmContract(
strconv.Itoa(chain.LatestCodeID),
`{"count": "0"}`, "salt",
transferCoin.String(),
fmt.Sprintf("%duluna", stabilityFee), "300000", "test")
"test", gasLimit, sdk.NewCoins(transferCoin))

contracts, err = node.QueryContractsFromID(chain.LatestCodeID)
s.Require().NoError(err)
s.Require().Len(contracts, 2, "Wrong number of contracts for the counter")

balance2, err := node.QuerySpecificBalance(testAddr, initialization.TerraDenom)
s.Require().NoError(err)
// balance1 - 100000000 - 100000000 * TaxRate
// balance1 - 100000000 - 100000000 * TaxRate - 2 (gas)
taxAmount = initialization.TaxRate.MulInt(transferAmount).TruncateInt()
s.Require().Equal(balance2.Amount, balance1.Amount.Sub(transferAmount).Sub(taxAmount))
s.Require().Equal(balance2.Amount, balance1.Amount.Sub(transferAmount).Sub(taxAmount).SubRaw(2))

contractAddr := contracts[0]
node.WasmExecute(contractAddr, `{"donate": {}}`, transferCoin.String(), fmt.Sprintf("%duluna", stabilityFee), "test")
node.WasmExecute(contractAddr, `{"donate": {}}`, transferCoin.String(), "test", gasLimit, sdk.NewCoins(transferCoin))

balance3, err := node.QuerySpecificBalance(testAddr, initialization.TerraDenom)
s.Require().NoError(err)
// balance2 - 100000000 - 100000000 * TaxRate
// balance2 - 100000000 - 100000000 * TaxRate - 2 (gas)
taxAmount = initialization.TaxRate.MulInt(transferAmount).TruncateInt()
s.Require().Equal(balance3.Amount, balance2.Amount.Sub(transferAmount).Sub(taxAmount))
s.Require().Equal(balance3.Amount, balance2.Amount.Sub(transferAmount).Sub(taxAmount).SubRaw(2))
}

func (s *IntegrationTestSuite) TestFeeTaxGrant() {
chain := s.configurer.GetChainConfig(0)
node, err := chain.GetDefaultNode()
s.Require().NoError(err)

transferAmount := sdkmath.NewInt(100000000)
transferCoin := sdk.NewCoin(initialization.TerraDenom, transferAmount)

validatorAddr := node.GetWallet(initialization.ValidatorWalletName)
s.Require().NotEqual(validatorAddr, "")

test1Addr := node.CreateWallet("test1")
test2Addr := node.CreateWallet("test2")

// Test 1: try bank send with grant
gasLimit := transferCoin.Amount.MulRaw(initialization.E10).String()
node.BankSend(transferCoin.String(), validatorAddr, test1Addr, gasLimit, sdk.NewCoins(transferCoin))
node.BankSend(transferCoin.String(), validatorAddr, test1Addr, gasLimit, sdk.NewCoins(transferCoin))
node.BankSend(transferCoin.String(), validatorAddr, test2Addr, gasLimit, sdk.NewCoins(transferCoin))
node.GrantAddress(test2Addr, test1Addr, transferCoin.String(), "test2")

validatorBalance, err := node.QuerySpecificBalance(validatorAddr, initialization.TerraDenom)
s.Require().NoError(err)

node.BankSendFeeGrantWithWallet(transferCoin.String(), test1Addr, validatorAddr, test2Addr, "test1", gasLimit, sdk.NewCoins(transferCoin))

newValidatorBalance, err := node.QuerySpecificBalance(validatorAddr, initialization.TerraDenom)
s.Require().NoError(err)

balanceTest1, err := node.QuerySpecificBalance(test1Addr, initialization.TerraDenom)
s.Require().NoError(err)

balanceTest2, err := node.QuerySpecificBalance(test2Addr, initialization.TerraDenom)
s.Require().NoError(err)

s.Require().Equal(balanceTest1, transferCoin)
s.Require().Equal(newValidatorBalance, validatorBalance.Add(transferCoin))
// addr2 lost 2uluna to pay for grant msg's gas, 100000000 * TaxRate + 2uluna to pay for bank send msg's tx fees,
s.Require().Equal(balanceTest2.Amount, transferAmount.Sub(initialization.TaxRate.MulInt(transferAmount).TruncateInt()).SubRaw(4))

// Test 2: try bank send with grant but pay by multiple fees denom
}
Loading

0 comments on commit 644d5f4

Please sign in to comment.