Skip to content

Commit

Permalink
- working version of reverse charge handling
Browse files Browse the repository at this point in the history
  • Loading branch information
StrathCole committed Oct 11, 2024
1 parent 5387458 commit 254e6e2
Show file tree
Hide file tree
Showing 17 changed files with 368 additions and 242 deletions.
1 change: 1 addition & 0 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ func NewAppKeepers(
appKeepers.BankKeeper,
appKeepers.TreasuryKeeper,
appKeepers.AccountKeeper,
appKeepers.TaxKeeper,
appCodec,
appKeepers.TransferKeeper,
)
Expand Down
6 changes: 4 additions & 2 deletions app/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ import (
ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint"

taxbank "github.com/classic-terra/core/v3/x/tax/modules/bank"
taxmarket "github.com/classic-terra/core/v3/x/tax/modules/market"
taxwasm "github.com/classic-terra/core/v3/x/tax/modules/wasm"
taxtypes "github.com/classic-terra/core/v3/x/tax/types"

// unnamed import of statik for swagger UI support
Expand Down Expand Up @@ -183,10 +185,10 @@ func appModules(
transfer.NewAppModule(app.TransferKeeper),
ibcfee.NewAppModule(app.IBCFeeKeeper),
ica.NewAppModule(&app.ICAControllerKeeper, &app.ICAHostKeeper),
market.NewAppModule(appCodec, app.MarketKeeper, app.AccountKeeper, app.BankKeeper, app.OracleKeeper),
taxmarket.NewAppModule(appCodec, app.MarketKeeper, app.AccountKeeper, app.TreasuryKeeper, app.BankKeeper, app.OracleKeeper, app.TaxKeeper),
oracle.NewAppModule(appCodec, app.OracleKeeper, app.AccountKeeper, app.BankKeeper),
treasury.NewAppModule(appCodec, app.TreasuryKeeper),
wasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)),
taxwasm.NewAppModule(appCodec, &app.WasmKeeper, app.StakingKeeper, app.AccountKeeper, app.AccountKeeper, app.TreasuryKeeper, app.TaxKeeper, app.BankKeeper, app.MsgServiceRouter(), app.GetSubspace(wasmtypes.ModuleName)),
dyncomm.NewAppModule(appCodec, app.DyncommKeeper, app.StakingKeeper),
ibchooks.NewAppModule(app.AccountKeeper),
consensus.NewAppModule(appCodec, app.ConsensusParamsKeeper),
Expand Down
1 change: 0 additions & 1 deletion custom/auth/ante/ante_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ func createTestApp(isCheckTx bool, tempDir string) (*terraapp.TerraApp, sdk.Cont
app.TreasuryKeeper.SetParams(ctx, treasurytypes.DefaultParams())
app.DistrKeeper.SetParams(ctx, distributiontypes.DefaultParams())
app.DistrKeeper.SetFeePool(ctx, distributiontypes.InitialFeePool())
//app.TaxKeeper.SetParams(ctx, taxtypes.DefaultParams())

return app, ctx
}
Expand Down
10 changes: 5 additions & 5 deletions custom/auth/ante/fee.go
Original file line number Diff line number Diff line change
Expand Up @@ -236,20 +236,20 @@ func (fd FeeDecorator) checkTxFee(ctx sdk.Context, tx sdk.Tx, taxes sdk.Coins) (

requiredFees := requiredGasFees.Add(taxes...)

fmt.Println("requiredFees", requiredFees, "feeCoins", feeCoins, "requiredGasFees", requiredGasFees, "taxes", taxes, "minGasPrices", minGasPrices)
// fmt.Println("requiredFees", requiredFees, "feeCoins", feeCoins, "requiredGasFees", requiredGasFees, "taxes", taxes, "minGasPrices", minGasPrices)

// Check required fees
if !requiredFees.IsZero() && !feeCoins.IsAnyGTE(requiredFees) {
// we don't have enough for tax and gas fees. But do we have enough for gas alone?
if !feeCoins.IsAnyGTE(requiredGasFees) {
if !requiredGasFees.IsZero() && !feeCoins.IsAnyGTE(requiredGasFees) {
return 0, false, errorsmod.Wrapf(sdkerrors.ErrInsufficientFee, "insufficient fees; got: %q, required: %q = %q(gas) + %q(stability)", feeCoins, requiredFees, requiredGasFees, taxes)
}

// we have enough for gas fees but not for tax fees
reverseCharge = true
ctx.Logger().Info("Insufficient fees to pay for gas and taxes (doing reverse charge)", "sentFee", feeCoins, "taxes", taxes, "requiredGasFees", requiredGasFees, "requiredFees", requiredFees, "minGasPrices", minGasPrices)
} else {
ctx.Logger().Info("Sufficient fees to pay for gas and taxes (doing normal tax charge)", "sentFee", feeCoins, "taxes", taxes, "requiredGasFees", requiredGasFees, "requiredFees", requiredFees, "minGasPrices", minGasPrices)
// ctx.Logger().Info("Insufficient fees to pay for gas and taxes (doing reverse charge)", "sentFee", feeCoins, "taxes", taxes, "requiredGasFees", requiredGasFees, "requiredFees", requiredFees)
// } else {
// ctx.Logger().Info("Sufficient fees to pay for gas and taxes (doing normal tax charge)", "sentFee", feeCoins, "taxes", taxes, "requiredGasFees", requiredGasFees, "requiredFees", requiredFees)
}
}

Expand Down
7 changes: 4 additions & 3 deletions custom/auth/ante/fee_tax.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"regexp"
"strings"

wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
sdk "github.com/cosmos/cosmos-sdk/types"
authz "github.com/cosmos/cosmos-sdk/x/authz"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
Expand Down Expand Up @@ -54,7 +53,9 @@ func FilterMsgAndComputeTax(ctx sdk.Context, tk TreasuryKeeper, simulate bool, m
case *marketexported.MsgSwapSend:
taxes = taxes.Add(computeTax(ctx, tk, sdk.NewCoins(msg.OfferCoin), simulate)...)

case *wasmtypes.MsgInstantiateContract:
// The contract messages were disabled to remove double-taxation
// whenever a contract sends funds to a wallet, it is taxed (deducted from sent amount)
/*case *wasmtypes.MsgInstantiateContract:
taxes = taxes.Add(computeTax(ctx, tk, msg.Funds, simulate)...)
case *wasmtypes.MsgInstantiateContract2:
Expand All @@ -64,7 +65,7 @@ func FilterMsgAndComputeTax(ctx sdk.Context, tk TreasuryKeeper, simulate bool, m
if !tk.HasBurnTaxExemptionContract(ctx, msg.Contract) {
taxes = taxes.Add(computeTax(ctx, tk, msg.Funds, simulate)...)
}

*/
case *authz.MsgExec:
messages, err := msg.GetMessages()
if err == nil {
Expand Down
84 changes: 56 additions & 28 deletions custom/auth/ante/fee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
core "github.com/classic-terra/core/v3/types"
markettypes "github.com/classic-terra/core/v3/x/market/types"
oracletypes "github.com/classic-terra/core/v3/x/oracle/types"
taxtypes "github.com/classic-terra/core/v3/x/tax/types"
)

func (s *AnteTestSuite) TestDeductFeeDecorator_ZeroGas() {
Expand Down Expand Up @@ -326,8 +327,10 @@ func (s *AnteTestSuite) TestEnsureMempoolFeesMultiSend() {
s.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroSDRDenom, expectedTax)))
tx, err = s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID())
s.Require().NoError(err)
_, err = antehandler(s.ctx, tx, false)
s.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax")
newCtx, err := antehandler(s.ctx, tx, false)
s.Require().NoError(err, "Decorator should not have errored on missing tax (reverse charge)")
s.Require().Equal(true, newCtx.Value(taxtypes.ContextKeyTaxReverseCharge).(bool))
//s.Require().Error(err, "Decorator should errored on low fee for local gasPrice + tax")

Check failure on line 333 in custom/auth/ante/fee_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

commentFormatting: put a space between `//` and comment text (gocritic)

// must pass with tax
s.txBuilder.SetFeeAmount(sdk.NewCoins(sdk.NewCoin(core.MicroSDRDenom, expectedTax.Add(expectedTax))))
Expand Down Expand Up @@ -527,11 +530,12 @@ func (s *AnteTestSuite) TestTaxExemption() {
feeAmt := int64(1000)

cases := []struct {
name string
msgSigner cryptotypes.PrivKey
msgCreator func() []sdk.Msg
minFeeAmount int64
expectProceeds int64
name string
msgSigner cryptotypes.PrivKey
msgCreator func() []sdk.Msg
minFeeAmount int64
expectProceeds int64
expectReverseCharge bool
}{
{
name: "MsgSend(exemption -> exemption)",
Expand All @@ -544,8 +548,9 @@ func (s *AnteTestSuite) TestTaxExemption() {

return msgs
},
minFeeAmount: 0,
expectProceeds: 0,
minFeeAmount: 0,
expectProceeds: 0,
expectReverseCharge: false,
}, {
name: "MsgSend(normal -> normal)",
msgSigner: privs[2],
Expand All @@ -558,8 +563,24 @@ func (s *AnteTestSuite) TestTaxExemption() {
return msgs
},
// tax this one hence burn amount is fee amount
minFeeAmount: feeAmt,
expectProceeds: feeAmt,
minFeeAmount: feeAmt,
expectProceeds: feeAmt,
expectReverseCharge: false,
}, {
name: "MsgSend(normal -> normal, reverse charge)",
msgSigner: privs[2],
msgCreator: func() []sdk.Msg {
var msgs []sdk.Msg

msg1 := banktypes.NewMsgSend(addrs[2], addrs[3], sdk.NewCoins(sendCoin))
msgs = append(msgs, msg1)

return msgs
},
// tax this one hence burn amount is fee amount
minFeeAmount: 0,
expectProceeds: 0,
expectReverseCharge: true,
}, {
name: "MsgExec(MsgSend(normal -> normal))",
msgSigner: privs[2],
Expand All @@ -572,8 +593,9 @@ func (s *AnteTestSuite) TestTaxExemption() {
return msgs
},
// tax this one hence burn amount is fee amount
minFeeAmount: feeAmt,
expectProceeds: feeAmt,
minFeeAmount: feeAmt,
expectProceeds: feeAmt,
expectReverseCharge: false,
}, {
name: "MsgSend(exemption -> normal), MsgSend(exemption -> exemption)",
msgSigner: privs[0],
Expand All @@ -588,8 +610,9 @@ func (s *AnteTestSuite) TestTaxExemption() {
return msgs
},
// tax this one hence burn amount is fee amount
minFeeAmount: feeAmt,
expectProceeds: feeAmt,
minFeeAmount: feeAmt,
expectProceeds: feeAmt,
expectReverseCharge: false,
}, {
name: "MsgSend(exemption -> exemption), MsgMultiSend(exemption -> normal, exemption -> exemption)",
msgSigner: privs[0],
Expand Down Expand Up @@ -624,8 +647,9 @@ func (s *AnteTestSuite) TestTaxExemption() {

return msgs
},
minFeeAmount: feeAmt * 2,
expectProceeds: feeAmt * 2,
minFeeAmount: feeAmt * 2,
expectProceeds: feeAmt * 2,
expectReverseCharge: false,
}, {
name: "MsgExecuteContract(exemption), MsgExecuteContract(normal)",
msgSigner: privs[3],
Expand Down Expand Up @@ -674,12 +698,14 @@ func (s *AnteTestSuite) TestTaxExemption() {
msgs = append(msgs, msg2)
return msgs
},
minFeeAmount: feeAmt,
expectProceeds: feeAmt,
minFeeAmount: 0, // sending to contract is not taxed
expectProceeds: 0,
expectReverseCharge: false,
},
}

// there should be no coin in burn module
// run once with reverse charge and once without
for _, c := range cases {
s.SetupTest(true) // setup
require := s.Require()
Expand Down Expand Up @@ -719,7 +745,7 @@ func (s *AnteTestSuite) TestTaxExemption() {
tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID())
require.NoError(err)

_, err = antehandler(s.ctx, tx, false)
newCtx, err := antehandler(s.ctx, tx, false)
require.NoError(err)

// check fee collector
Expand All @@ -730,6 +756,8 @@ func (s *AnteTestSuite) TestTaxExemption() {
// check tax proceeds
taxProceeds := s.app.TreasuryKeeper.PeekEpochTaxProceeds(s.ctx)
require.Equal(taxProceeds, sdk.NewCoins(sdk.NewCoin(core.MicroSDRDenom, sdk.NewInt(c.expectProceeds))))

require.Equal(newCtx.Value(taxtypes.ContextKeyTaxReverseCharge), c.expectReverseCharge)
}
}

Expand Down Expand Up @@ -774,7 +802,7 @@ func (s *AnteTestSuite) runBurnSplitTaxTest(burnSplitRate sdk.Dec, oracleSplitRa
// Set burn split tax
tk.SetBurnSplitRate(s.ctx, burnSplitRate)
tk.SetOracleSplitRate(s.ctx, oracleSplitRate)
taxRate := tk.GetTaxRate(s.ctx)
//taxRate := tk.GetTaxRate(s.ctx)

Check failure on line 805 in custom/auth/ante/fee_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

commentFormatting: put a space between `//` and comment text (gocritic)

// Set community tax
dkParams := dk.GetParams(s.ctx)
Expand Down Expand Up @@ -812,17 +840,17 @@ func (s *AnteTestSuite) runBurnSplitTaxTest(burnSplitRate sdk.Dec, oracleSplitRa
// Set IsCheckTx to true
s.ctx = s.ctx.WithIsCheckTx(true)

feeCollector := ak.GetModuleAccount(s.ctx, authtypes.FeeCollectorName)
// feeCollector := ak.GetModuleAccount(s.ctx, authtypes.FeeCollectorName)

amountFeeBefore := bk.GetAllBalances(s.ctx, feeCollector.GetAddress())
//amountFeeBefore := bk.GetAllBalances(s.ctx, feeCollector.GetAddress())

Check failure on line 845 in custom/auth/ante/fee_test.go

View workflow job for this annotation

GitHub Actions / golangci-lint

commentFormatting: put a space between `//` and comment text (gocritic)

totalSupplyBefore, _, err := bk.GetPaginatedTotalSupply(s.ctx, &query.PageRequest{})
require.NoError(err)
fmt.Printf(
/*fmt.Printf(
"Before: TotalSupply %v, FeeCollector %v\n",
totalSupplyBefore,
amountFeeBefore,
)
)*/

// send tx to BurnTaxFeeDecorator antehandler
_, err = antehandler(s.ctx, tx, false)
Expand Down Expand Up @@ -855,7 +883,7 @@ func (s *AnteTestSuite) runBurnSplitTaxTest(burnSplitRate sdk.Dec, oracleSplitRa
expectedDistrCoins := distributionDeltaCoins.Sub(expectedOracleCoins)

// expected: community pool 50%
fmt.Printf("-- sendCoins %+v, BurnTax %+v, BurnSplitRate %+v, OracleSplitRate %+v, CommunityTax %+v, CTaxApplied %+v, OracleCoins %+v, DistrCoins %+v\n", sendCoins.AmountOf(core.MicroSDRDenom), taxRate, burnSplitRate, oracleSplitRate, communityTax, applyCommunityTax, expectedOracleCoins, expectedDistrCoins)
// fmt.Printf("-- sendCoins %+v, BurnTax %+v, BurnSplitRate %+v, OracleSplitRate %+v, CommunityTax %+v, CTaxApplied %+v, OracleCoins %+v, DistrCoins %+v\n", sendCoins.AmountOf(core.MicroSDRDenom), taxRate, burnSplitRate, oracleSplitRate, communityTax, applyCommunityTax, expectedOracleCoins, expectedDistrCoins)
require.Equal(feeCollectorAfter, sdk.NewCoins(sdk.NewCoin(core.MicroSDRDenom, expectedDistrCoins)))
require.Equal(oracleAfter, sdk.NewCoins(sdk.NewCoin(core.MicroSDRDenom, expectedOracleCoins)))
require.Equal(communityPoolAfter, sdk.NewCoins(sdk.NewCoin(core.MicroSDRDenom, expectedCommunityCoins)))
Expand Down Expand Up @@ -890,11 +918,11 @@ func (s *AnteTestSuite) runBurnSplitTaxTest(burnSplitRate sdk.Dec, oracleSplitRa
)
}

fmt.Printf(
/*fmt.Printf(
"After: TotalSupply %v, FeeCollector %v\n",
totalSupplyAfter,
feeCollectorAfter,
)
)*/
}

// go test -v -run ^TestAnteTestSuite/TestEnsureIBCUntaxed$ github.com/classic-terra/core/v3/custom/auth/ante
Expand Down
Loading

0 comments on commit 254e6e2

Please sign in to comment.