From 33c613abec79b9a62847b2dd13e8f039dcaf6fd8 Mon Sep 17 00:00:00 2001 From: Edward Kim Date: Tue, 26 Jul 2022 01:59:58 -0400 Subject: [PATCH 1/2] Burn Tax via utilization of existing Stability Tax code --- custom/auth/ante/ante.go | 6 +- custom/auth/ante/burntax.go | 61 +++++ custom/auth/ante/burntax_test.go | 91 +++++++ custom/auth/ante/expected_keeper.go | 6 + custom/auth/ante/tax.go | 7 +- custom/auth/ante/tax_test.go | 356 ++++++++++++++++++++++++++++ go.mod | 7 +- go.sum | 4 +- x/treasury/keeper/keeper.go | 10 +- 9 files changed, 534 insertions(+), 14 deletions(-) create mode 100644 custom/auth/ante/burntax.go create mode 100644 custom/auth/ante/burntax_test.go diff --git a/custom/auth/ante/ante.go b/custom/auth/ante/ante.go index dd1458962..e920f2c12 100644 --- a/custom/auth/ante/ante.go +++ b/custom/auth/ante/ante.go @@ -8,13 +8,12 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" cosmosante "github.com/cosmos/cosmos-sdk/x/auth/ante" "github.com/cosmos/cosmos-sdk/x/auth/signing" - "github.com/cosmos/cosmos-sdk/x/auth/types" ) // HandlerOptions are the options required for constructing a default SDK AnteHandler. type HandlerOptions struct { AccountKeeper cosmosante.AccountKeeper - BankKeeper types.BankKeeper + BankKeeper BankKeeper FeegrantKeeper cosmosante.FeegrantKeeper OracleKeeper OracleKeeper TreasuryKeeper TreasuryKeeper @@ -62,7 +61,8 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { cosmosante.NewValidateMemoDecorator(options.AccountKeeper), cosmosante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), cosmosante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper), - cosmosante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators + NewBurnTaxFeeDecorator(options.TreasuryKeeper, options.BankKeeper), // burn tax proceeds + cosmosante.NewSetPubKeyDecorator(options.AccountKeeper), // SetPubKeyDecorator must be called before all signature verification decorators cosmosante.NewValidateSigCountDecorator(options.AccountKeeper), cosmosante.NewSigGasConsumeDecorator(options.AccountKeeper, sigGasConsumer), NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler), diff --git a/custom/auth/ante/burntax.go b/custom/auth/ante/burntax.go new file mode 100644 index 000000000..e4cc60eb6 --- /dev/null +++ b/custom/auth/ante/burntax.go @@ -0,0 +1,61 @@ +package ante + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/types" + treasury "github.com/terra-money/core/x/treasury/types" +) + +// TaxPowerUpgradeHeight is when taxes are allowed to go into effect +// This will still need a parameter change proposal, but can be activated +// anytime after this height +const TaxPowerUpgradeHeight = 9346889 + +// BurnTaxFeeDecorator will immediately burn the collected Tax +type BurnTaxFeeDecorator struct { + treasuryKeeper TreasuryKeeper + bankKeeper BankKeeper +} + +// NewBurnTaxFeeDecorator returns new tax fee decorator instance +func NewBurnTaxFeeDecorator(treasuryKeeper TreasuryKeeper, bankKeeper BankKeeper) BurnTaxFeeDecorator { + return BurnTaxFeeDecorator{ + treasuryKeeper: treasuryKeeper, + bankKeeper: bankKeeper, + } +} + +// AnteHandle handles msg tax fee checking +func (btfd BurnTaxFeeDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) { + // Do not proceed if you are below this block height + currHeight := ctx.BlockHeight() + if currHeight < TaxPowerUpgradeHeight { + return next(ctx, tx, simulate) + } + + feeTx, ok := tx.(sdk.FeeTx) + if !ok { + return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "Tx must be a FeeTx") + } + + msgs := feeTx.GetMsgs() + + // At this point we have already run the DeductFees AnteHandler and taken the fees from the sending account + // Now we remove the taxes from the gas reward and immediately burn it + + if !simulate { + // Compute taxes again. + taxes := FilterMsgAndComputeTax(ctx, btfd.treasuryKeeper, msgs...) + + // Record tax proceeds + if !taxes.IsZero() { + err = btfd.bankKeeper.SendCoinsFromModuleToModule(ctx, types.FeeCollectorName, treasury.BurnModuleName, taxes) + if err != nil { + return ctx, sdkerrors.Wrapf(sdkerrors.ErrInsufficientFunds, err.Error()) + } + } + } + + return next(ctx, tx, simulate) +} diff --git a/custom/auth/ante/burntax_test.go b/custom/auth/ante/burntax_test.go new file mode 100644 index 000000000..eec77d905 --- /dev/null +++ b/custom/auth/ante/burntax_test.go @@ -0,0 +1,91 @@ +package ante_test + +import ( + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" + "github.com/cosmos/cosmos-sdk/testutil/testdata" + sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + + "github.com/terra-money/core/custom/auth/ante" + core "github.com/terra-money/core/types" + "github.com/cosmos/cosmos-sdk/types/query" + "github.com/cosmos/cosmos-sdk/x/auth/types" + minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" +) + +func (suite *AnteTestSuite) TestEnsureBurnTaxModule() { + suite.SetupTest(true) // setup + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + mfd := ante.NewBurnTaxFeeDecorator(suite.app.TreasuryKeeper, suite.app.BankKeeper) + antehandler := sdk.ChainAnteDecorators(mfd) + + // keys and addresses + priv1, _, addr1 := testdata.KeyTestPubAddr() + + // msg and signatures + sendAmount := int64(1000000) + sendCoins := sdk.NewCoins(sdk.NewInt64Coin(core.MicroSDRDenom, sendAmount)) + msg := banktypes.NewMsgSend(addr1, addr1, sendCoins) + + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // set zero gas prices + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins()) + + // Set IsCheckTx to true + suite.ctx = suite.ctx.WithIsCheckTx(true) + + // Luna must pass without burn before the specified tax block height + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored when block height is 1") + + // Set the blockheight past the tax height block + suite.ctx = suite.ctx.WithBlockHeight(10000000) + // antehandler errors with insufficient fees due to tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax") + + tk := suite.app.TreasuryKeeper + expectedTax := tk.GetTaxRate(suite.ctx).MulInt64(sendAmount).TruncateInt() + if taxCap := tk.GetTaxCap(suite.ctx, core.MicroSDRDenom); expectedTax.GT(taxCap) { + expectedTax = taxCap + } + + taxes := sdk.NewCoins(sdk.NewInt64Coin(core.MicroSDRDenom, expectedTax.Int64())) + + bk := suite.app.BankKeeper + bk.MintCoins(suite.ctx, minttypes.ModuleName, sendCoins) + + // Populate the FeeCollector module with taxes + bk.SendCoinsFromModuleToModule(suite.ctx, minttypes.ModuleName, types.FeeCollectorName, taxes) + feeCollector := suite.app.AccountKeeper.GetModuleAccount(suite.ctx, types.FeeCollectorName) + + amountFee := bk.GetAllBalances(suite.ctx, feeCollector.GetAddress()) + suite.Require().Equal(amountFee, taxes) + totalSupply, _, err := bk.GetPaginatedTotalSupply(suite.ctx, &query.PageRequest{}) + + // must pass with tax and burn + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored on fee higher than local gasPrice") + + // Burn the taxes + tk.BurnCoinsFromBurnAccount(suite.ctx) + suite.Require().NoError(err) + + supplyAfterBurn, _, err := bk.GetPaginatedTotalSupply(suite.ctx, &query.PageRequest{}) + + // Total supply should have decreased by the tax amount + suite.Require().Equal(taxes, totalSupply.Sub(supplyAfterBurn)) + + +} + diff --git a/custom/auth/ante/expected_keeper.go b/custom/auth/ante/expected_keeper.go index 9cb3675ab..c03a9b5f5 100644 --- a/custom/auth/ante/expected_keeper.go +++ b/custom/auth/ante/expected_keeper.go @@ -15,3 +15,9 @@ type TreasuryKeeper interface { type OracleKeeper interface { ValidateFeeder(ctx sdk.Context, feederAddr sdk.AccAddress, validatorAddr sdk.ValAddress) error } + +// BankKeeper defines the contract needed for supply related APIs (noalias) +type BankKeeper interface { + SendCoinsFromAccountToModule(ctx sdk.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error + SendCoinsFromModuleToModule(ctx sdk.Context, senderModule string, recipientModule string, amt sdk.Coins) error +} diff --git a/custom/auth/ante/tax.go b/custom/auth/ante/tax.go index 8db5be13b..dc746a3ad 100644 --- a/custom/auth/ante/tax.go +++ b/custom/auth/ante/tax.go @@ -144,6 +144,7 @@ func FilterMsgAndComputeTax(ctx sdk.Context, tk TreasuryKeeper, msgs ...sdk.Msg) // computes the stability tax according to tax-rate and tax-cap func computeTax(ctx sdk.Context, tk TreasuryKeeper, principal sdk.Coins) sdk.Coins { + currHeight := ctx.BlockHeight() taxRate := tk.GetTaxRate(ctx) if taxRate.Equal(sdk.ZeroDec()) { return sdk.Coins{} @@ -151,7 +152,11 @@ func computeTax(ctx sdk.Context, tk TreasuryKeeper, principal sdk.Coins) sdk.Coi taxes := sdk.Coins{} for _, coin := range principal { - if coin.Denom == core.MicroLunaDenom || coin.Denom == sdk.DefaultBondDenom { + // Originally only a stability tax on UST. Changed to tax Luna as well after TaxPowerUpgradeHeight + if (coin.Denom == core.MicroLunaDenom || coin.Denom == sdk.DefaultBondDenom) && currHeight < TaxPowerUpgradeHeight { + continue + } + if coin.Denom == sdk.DefaultBondDenom { continue } diff --git a/custom/auth/ante/tax_test.go b/custom/auth/ante/tax_test.go index 29a85b4d0..48737f876 100644 --- a/custom/auth/ante/tax_test.go +++ b/custom/auth/ante/tax_test.go @@ -384,3 +384,359 @@ func (suite *AnteTestSuite) TestEnsureMempoolFeesExec() { _, err = antehandler(suite.ctx, tx, false) suite.Require().NoError(err, "Decorator should not have errored on fee higher than local gasPrice") } + +func (suite *AnteTestSuite) TestEnsureMempoolFeesSendLunaTax() { + suite.SetupTest(true) // setup + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + mfd := ante.NewTaxFeeDecorator(suite.app.TreasuryKeeper) + antehandler := sdk.ChainAnteDecorators(mfd) + + // keys and addresses + priv1, _, addr1 := testdata.KeyTestPubAddr() + + // msg and signatures + sendAmount := int64(1000000) + sendCoins := sdk.NewCoins(sdk.NewInt64Coin(core.MicroLunaDenom, sendAmount)) + msg := banktypes.NewMsgSend(addr1, addr1, sendCoins) + + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // set zero gas prices + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins()) + + // Set IsCheckTx to true + suite.ctx = suite.ctx.WithIsCheckTx(true) + + // Luna must pass with tax before the specified tax block height + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored when block height is 1") + + // Set the blockheight past the tax height block + suite.ctx = suite.ctx.WithBlockHeight(10000000) + // antehandler errors with insufficient fees due to tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax") + + tk := suite.app.TreasuryKeeper + expectedTax := tk.GetTaxRate(suite.ctx).MulInt64(sendAmount).TruncateInt() + if taxCap := tk.GetTaxCap(suite.ctx, core.MicroLunaDenom); expectedTax.GT(taxCap) { + expectedTax = taxCap + } + + // set tax amount + suite.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroLunaDenom, expectedTax))) + tx, err = suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // must pass with tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored on fee higher than local gasPrice") +} + +func (suite *AnteTestSuite) TestEnsureMempoolFeesSwapSendLunaTax() { + suite.SetupTest(true) // setup + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + mfd := ante.NewTaxFeeDecorator(suite.app.TreasuryKeeper) + antehandler := sdk.ChainAnteDecorators(mfd) + + // keys and addresses + priv1, _, addr1 := testdata.KeyTestPubAddr() + + // msg and signatures + sendAmount := int64(1000000) + sendCoin := sdk.NewInt64Coin(core.MicroLunaDenom, sendAmount) + msg := markettypes.NewMsgSwapSend(addr1, addr1, sendCoin, core.MicroKRWDenom) + + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // set zero gas prices + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins()) + + // Set IsCheckTx to true + suite.ctx = suite.ctx.WithIsCheckTx(true) + + // Luna must pass with tax before the specified tax block height + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored when block height is 1") + + // Set the blockheight past the tax height block + suite.ctx = suite.ctx.WithBlockHeight(10000000) + // antehandler errors with insufficient fees due to tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax") + + tk := suite.app.TreasuryKeeper + expectedTax := tk.GetTaxRate(suite.ctx).MulInt64(sendAmount).TruncateInt() + if taxCap := tk.GetTaxCap(suite.ctx, core.MicroLunaDenom); expectedTax.GT(taxCap) { + expectedTax = taxCap + } + + // set tax amount + suite.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroLunaDenom, expectedTax))) + tx, err = suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // must pass with tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored on fee higher than local gasPrice") +} + +func (suite *AnteTestSuite) TestEnsureMempoolFeesMultiSendLunaTax() { + suite.SetupTest(true) // setup + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + mfd := ante.NewTaxFeeDecorator(suite.app.TreasuryKeeper) + antehandler := sdk.ChainAnteDecorators(mfd) + + // keys and addresses + priv1, _, addr1 := testdata.KeyTestPubAddr() + + // msg and signatures + sendAmount := int64(1000000) + sendCoins := sdk.NewCoins(sdk.NewInt64Coin(core.MicroLunaDenom, sendAmount)) + msg := banktypes.NewMsgMultiSend( + []banktypes.Input{ + banktypes.NewInput(addr1, sendCoins), + banktypes.NewInput(addr1, sendCoins), + }, + []banktypes.Output{ + banktypes.NewOutput(addr1, sendCoins.Add(sendCoins...)), + }, + ) + + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // set zero gas prices + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins()) + + // Set IsCheckTx to true + suite.ctx = suite.ctx.WithIsCheckTx(true) + + // Luna must pass with tax before the specified tax block height + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored when block height is 1") + + // Set the blockheight past the tax height block + suite.ctx = suite.ctx.WithBlockHeight(10000000) + // antehandler errors with insufficient fees due to tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax") + + tk := suite.app.TreasuryKeeper + expectedTax := tk.GetTaxRate(suite.ctx).MulInt64(sendAmount).TruncateInt() + if taxCap := tk.GetTaxCap(suite.ctx, core.MicroLunaDenom); expectedTax.GT(taxCap) { + expectedTax = taxCap + } + + // set tax amount + suite.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroLunaDenom, expectedTax))) + tx, err = suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + _, err = antehandler(suite.ctx, tx, false) + suite.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax") + + // must pass with tax + suite.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroLunaDenom, expectedTax.Add(expectedTax)))) + tx, err = suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored on fee higher than local gasPrice") +} + +func (suite *AnteTestSuite) TestEnsureMempoolFeesInstantiateContractLunaTax() { + + suite.SetupTest(true) // setup + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + mfd := ante.NewTaxFeeDecorator(suite.app.TreasuryKeeper) + antehandler := sdk.ChainAnteDecorators(mfd) + + // keys and addresses + priv1, _, addr1 := testdata.KeyTestPubAddr() + + // msg and signatures + sendAmount := int64(1000000) + sendCoins := sdk.NewCoins(sdk.NewInt64Coin(core.MicroLunaDenom, sendAmount)) + msg := wasmtypes.NewMsgInstantiateContract(addr1, addr1, 0, []byte{}, sendCoins) + + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // set zero gas prices + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins()) + + // Set IsCheckTx to true + suite.ctx = suite.ctx.WithIsCheckTx(true) + + // Luna must pass with tax before the specified tax block height + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored when block height is 1") + + // Set the blockheight past the tax height block + suite.ctx = suite.ctx.WithBlockHeight(10000000) + // antehandler errors with insufficient fees due to tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax") + + tk := suite.app.TreasuryKeeper + expectedTax := tk.GetTaxRate(suite.ctx).MulInt64(sendAmount).TruncateInt() + if taxCap := tk.GetTaxCap(suite.ctx, core.MicroLunaDenom); expectedTax.GT(taxCap) { + expectedTax = taxCap + } + + // set tax amount + suite.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroLunaDenom, expectedTax))) + tx, err = suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // must pass with tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored on fee higher than local gasPrice") +} + +func (suite *AnteTestSuite) TestEnsureMempoolFeesExecuteContractLunaTax() { + + suite.SetupTest(true) // setup + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + mfd := ante.NewTaxFeeDecorator(suite.app.TreasuryKeeper) + antehandler := sdk.ChainAnteDecorators(mfd) + + // keys and addresses + priv1, _, addr1 := testdata.KeyTestPubAddr() + + // msg and signatures + sendAmount := int64(1000000) + sendCoins := sdk.NewCoins(sdk.NewInt64Coin(core.MicroLunaDenom, sendAmount)) + msg := wasmtypes.NewMsgExecuteContract(addr1, addr1, []byte{}, sendCoins) + + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + suite.Require().NoError(suite.txBuilder.SetMsgs(msg)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // set zero gas prices + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins()) + + // Set IsCheckTx to true + suite.ctx = suite.ctx.WithIsCheckTx(true) + + // Luna must pass with tax before the specified tax block height + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored when block height is 1") + + // Set the blockheight past the tax height block + suite.ctx = suite.ctx.WithBlockHeight(10000000) + // antehandler errors with insufficient fees due to tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax") + + tk := suite.app.TreasuryKeeper + expectedTax := tk.GetTaxRate(suite.ctx).MulInt64(sendAmount).TruncateInt() + if taxCap := tk.GetTaxCap(suite.ctx, core.MicroLunaDenom); expectedTax.GT(taxCap) { + expectedTax = taxCap + } + + // set tax amount + suite.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroLunaDenom, expectedTax))) + tx, err = suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // must pass with tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored on fee higher than local gasPrice") +} + +func (suite *AnteTestSuite) TestEnsureMempoolFeesExecLunaTax() { + + suite.SetupTest(true) // setup + suite.txBuilder = suite.clientCtx.TxConfig.NewTxBuilder() + + mfd := ante.NewTaxFeeDecorator(suite.app.TreasuryKeeper) + antehandler := sdk.ChainAnteDecorators(mfd) + + // keys and addresses + priv1, _, addr1 := testdata.KeyTestPubAddr() + + // msg and signatures + sendAmount := int64(1000000) + sendCoins := sdk.NewCoins(sdk.NewInt64Coin(core.MicroLunaDenom, sendAmount)) + msg := authz.NewMsgExec(addr1, []sdk.Msg{banktypes.NewMsgSend(addr1, addr1, sendCoins)}) + + feeAmount := testdata.NewTestFeeAmount() + gasLimit := testdata.NewTestGasLimit() + suite.Require().NoError(suite.txBuilder.SetMsgs(&msg)) + suite.txBuilder.SetFeeAmount(feeAmount) + suite.txBuilder.SetGasLimit(gasLimit) + + privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} + tx, err := suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // set zero gas prices + suite.ctx = suite.ctx.WithMinGasPrices(sdk.NewDecCoins()) + + // Set IsCheckTx to true + suite.ctx = suite.ctx.WithIsCheckTx(true) + + // Luna must pass with tax before the specified tax block height + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored when block height is 1") + + // Set the blockheight past the tax height block + suite.ctx = suite.ctx.WithBlockHeight(10000000) + // antehandler errors with insufficient fees due to tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax") + + tk := suite.app.TreasuryKeeper + expectedTax := tk.GetTaxRate(suite.ctx).MulInt64(sendAmount).TruncateInt() + if taxCap := tk.GetTaxCap(suite.ctx, core.MicroLunaDenom); expectedTax.GT(taxCap) { + expectedTax = taxCap + } + + // set tax amount + suite.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroLunaDenom, expectedTax))) + tx, err = suite.CreateTestTx(privs, accNums, accSeqs, suite.ctx.ChainID()) + suite.Require().NoError(err) + + // must pass with tax + _, err = antehandler(suite.ctx, tx, false) + suite.Require().NoError(err, "Decorator should not have errored on fee higher than local gasPrice") +} diff --git a/go.mod b/go.mod index 43a219c90..c2bd3119d 100644 --- a/go.mod +++ b/go.mod @@ -122,12 +122,7 @@ require ( replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 - - // Commit 515df8b16c89 points the release/v0.44.x branch with the following - // security patches: - // - // - https://github.com/terra-money/cosmos-sdk/pull/63 - github.com/cosmos/cosmos-sdk => github.com/terra-money/cosmos-sdk v0.44.6-0.20220512154111-515df8b16c89 + github.com/cosmos/cosmos-sdk => github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220726045748-fad649d1bee6 github.com/cosmos/ledger-cosmos-go => github.com/terra-money/ledger-terra-go v0.11.2 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/tecbot/gorocksdb => github.com/cosmos/gorocksdb v1.2.0 diff --git a/go.sum b/go.sum index a3a3c18e1..57bdb2bbc 100644 --- a/go.sum +++ b/go.sum @@ -800,12 +800,12 @@ github.com/tendermint/tm-db v0.5.1/go.mod h1:g92zWjHpCYlEvQXvy9M168Su8V1IBEeawpX github.com/tendermint/tm-db v0.6.4/go.mod h1:dptYhIpJ2M5kUuenLr+Yyf3zQOv1SgBZcl8/BmWlMBw= github.com/tendermint/tm-db v0.6.6 h1:EzhaOfR0bdKyATqcd5PNeyeq8r+V4bRPHBfyFdD9kGM= github.com/tendermint/tm-db v0.6.6/go.mod h1:wP8d49A85B7/erz/r4YbKssKw6ylsO/hKtFk7E1aWZI= -github.com/terra-money/cosmos-sdk v0.44.6-0.20220512154111-515df8b16c89 h1:yz8rtH9EgEIpSEHMScM8C4SS3AdR38M8h68q8urSFo4= -github.com/terra-money/cosmos-sdk v0.44.6-0.20220512154111-515df8b16c89/go.mod h1:/tqCMnVCrX7F7iL2ALCsGdYmhx0jfgFG/50gP8jt6bI= github.com/terra-money/ledger-terra-go v0.11.2 h1:BVXZl+OhJOri6vFNjjVaTabRLApw9MuG7mxWL4V718c= github.com/terra-money/ledger-terra-go v0.11.2/go.mod h1:ClJ2XMj1ptcnONzKH+GhVPi7Y8pXIT+UzJ0TNt0tfZE= github.com/terra-money/tendermint v0.34.14-terra.2 h1:UYDDCI001ZNhs+aX09HjKVldUcz084q3RwLHUOSSZQU= github.com/terra-money/tendermint v0.34.14-terra.2/go.mod h1:FrwVm3TvsVicI9Z7FlucHV6Znfd5KBc/Lpp69cCwtk0= +github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220726045748-fad649d1bee6 h1:WmJy/ClgYLkVmW+p1PV/xe4kUQCoqhPmV48RRhB/D3Y= +github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220726045748-fad649d1bee6/go.mod h1:/tqCMnVCrX7F7iL2ALCsGdYmhx0jfgFG/50gP8jt6bI= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= diff --git a/x/treasury/keeper/keeper.go b/x/treasury/keeper/keeper.go index e5cd868ca..022c67218 100644 --- a/x/treasury/keeper/keeper.go +++ b/x/treasury/keeper/keeper.go @@ -14,6 +14,11 @@ import ( "github.com/terra-money/core/x/treasury/types" ) +// TaxPowerUpgradeHeight is when taxes are allowed to go into effect +// This will still need a parameter change proposal, but can be activated +// anytime after this height +const TaxPowerUpgradeHeight = 9346889 + // Keeper of the treasury store type Keeper struct { storeKey sdk.StoreKey @@ -124,8 +129,9 @@ func (k Keeper) SetTaxCap(ctx sdk.Context, denom string, cap sdk.Int) { // GetTaxCap gets the tax cap denominated in integer units of the reference {denom} func (k Keeper) GetTaxCap(ctx sdk.Context, denom string) sdk.Int { - // return zero tax cap for `uluna` - if denom == core.MicroLunaDenom { + currHeight := ctx.BlockHeight() + // Allow tax cap for uluna + if denom == core.MicroLunaDenom && currHeight < TaxPowerUpgradeHeight { return sdk.ZeroInt() } From 9b536c621236144905f08ed7d3a38c01050fbd5a Mon Sep 17 00:00:00 2001 From: Edward Kim Date: Wed, 3 Aug 2022 15:14:07 -0400 Subject: [PATCH 2/2] Added blockheights to the cosmos dependency --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index c2bd3119d..fe0014712 100644 --- a/go.mod +++ b/go.mod @@ -122,7 +122,7 @@ require ( replace ( github.com/99designs/keyring => github.com/cosmos/keyring v1.1.7-0.20210622111912-ef00f8ac3d76 - github.com/cosmos/cosmos-sdk => github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220726045748-fad649d1bee6 + github.com/cosmos/cosmos-sdk => github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220803190831-231b4e89cdb7 github.com/cosmos/ledger-cosmos-go => github.com/terra-money/ledger-terra-go v0.11.2 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/tecbot/gorocksdb => github.com/cosmos/gorocksdb v1.2.0 diff --git a/go.sum b/go.sum index 57bdb2bbc..9bde55a40 100644 --- a/go.sum +++ b/go.sum @@ -804,8 +804,8 @@ github.com/terra-money/ledger-terra-go v0.11.2 h1:BVXZl+OhJOri6vFNjjVaTabRLApw9M github.com/terra-money/ledger-terra-go v0.11.2/go.mod h1:ClJ2XMj1ptcnONzKH+GhVPi7Y8pXIT+UzJ0TNt0tfZE= github.com/terra-money/tendermint v0.34.14-terra.2 h1:UYDDCI001ZNhs+aX09HjKVldUcz084q3RwLHUOSSZQU= github.com/terra-money/tendermint v0.34.14-terra.2/go.mod h1:FrwVm3TvsVicI9Z7FlucHV6Znfd5KBc/Lpp69cCwtk0= -github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220726045748-fad649d1bee6 h1:WmJy/ClgYLkVmW+p1PV/xe4kUQCoqhPmV48RRhB/D3Y= -github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220726045748-fad649d1bee6/go.mod h1:/tqCMnVCrX7F7iL2ALCsGdYmhx0jfgFG/50gP8jt6bI= +github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220803190831-231b4e89cdb7 h1:RAuz6onHukywAmatpD66SyVfHEJTHjFI5HSc4kn4BF0= +github.com/terra-rebels/cosmos-sdk v0.44.6-0.20220803190831-231b4e89cdb7/go.mod h1:/tqCMnVCrX7F7iL2ALCsGdYmhx0jfgFG/50gP8jt6bI= github.com/tidwall/gjson v1.6.7/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=