Skip to content

Commit

Permalink
wip: add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
TropicalDog17 committed Nov 20, 2024
1 parent 96d1dec commit f48bef8
Show file tree
Hide file tree
Showing 2 changed files with 183 additions and 2 deletions.
4 changes: 2 additions & 2 deletions custom/auth/ante/fee.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,9 @@ func (fd FeeDecorator) checkTxFee(ctx sdk.Context, tx sdk.Tx, taxes sdk.Coins, n
allFees := requiredFees.Add(nonTaxableTaxes...)

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

Expand Down
181 changes: 181 additions & 0 deletions custom/auth/ante/fee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -859,6 +859,187 @@ func (s *AnteTestSuite) TestTaxExemption() {
})

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

View workflow job for this annotation

GitHub Actions / golangci-lint

File is not `gofumpt`-ed (gofumpt)
}

}

func (s *AnteTestSuite) TestTaxExemptionWithMultipleDenoms() {
// keys and addresses
var privs []cryptotypes.PrivKey
var addrs []sdk.AccAddress

// 0, 1: exemption
// 2, 3: normal
for i := 0; i < 4; i++ {
priv, _, addr := testdata.KeyTestPubAddr()
privs = append(privs, priv)
addrs = append(addrs, addr)
}

// use two different denoms but with same gas price
denom1 := "uaad"
denom2 := "ucud"

// set send amount
sendAmt := int64(1000000)
sendCoin := sdk.NewInt64Coin(denom1, sendAmt)
anotherSendCoin := sdk.NewInt64Coin(denom2, sendAmt)

cases := []struct {
name string
msgSigner cryptotypes.PrivKey
msgCreator func() []sdk.Msg
minFeeAmounts []sdk.Coin
expectProceeds sdk.Coins
expectReverseCharge bool
}{
{
name: "MsgSend(exemption -> exemption) with multiple fee denoms",
msgSigner: privs[0],
msgCreator: func() []sdk.Msg {
var msgs []sdk.Msg
msg1 := banktypes.NewMsgSend(addrs[0], addrs[1], sdk.NewCoins(sendCoin))
msgs = append(msgs, msg1)
return msgs
},
minFeeAmounts: []sdk.Coin{
sdk.NewInt64Coin(denom1, 0),
sdk.NewInt64Coin(denom2, 0),
},
expectProceeds: sdk.NewCoins(),
expectReverseCharge: false,
},
{
name: "MsgSend(normal -> normal) with multiple fee denoms",
msgSigner: privs[2],
msgCreator: func() []sdk.Msg {
var msgs []sdk.Msg
msg1 := banktypes.NewMsgSend(addrs[2], addrs[3], sdk.NewCoins(sendCoin, anotherSendCoin))
msgs = append(msgs, msg1)
return msgs
},
minFeeAmounts: []sdk.Coin{
sdk.NewInt64Coin(denom1, 5000),
sdk.NewInt64Coin(denom2, 5000),
},
expectProceeds: sdk.NewCoins(
sdk.NewInt64Coin(denom1, 5000),
sdk.NewInt64Coin(denom2, 5000),
),
expectReverseCharge: false,
},
{
name: "MsgSend(normal -> normal), enough taxes for both denoms",
msgSigner: privs[2],
msgCreator: func() []sdk.Msg {
var msgs []sdk.Msg
msg1 := banktypes.NewMsgSend(addrs[2], addrs[3], sdk.NewCoins(sendCoin, anotherSendCoin))
msgs = append(msgs, msg1)
return msgs
},
minFeeAmounts: []sdk.Coin{
sdk.NewInt64Coin(denom1, 5000),
sdk.NewInt64Coin(denom2, 5000),
},
expectProceeds: []sdk.Coin{
sdk.NewInt64Coin(denom1, 5000),
sdk.NewInt64Coin(denom2, 5000),
},
expectReverseCharge: false,
},
{
name: "MsgSend(normal -> normal), one denom not enough tax",
msgSigner: privs[2],
msgCreator: func() []sdk.Msg {
var msgs []sdk.Msg
msg1 := banktypes.NewMsgSend(addrs[2], addrs[3], sdk.NewCoins(sendCoin, anotherSendCoin))
msgs = append(msgs, msg1)
return msgs
},
minFeeAmounts: []sdk.Coin{
sdk.NewInt64Coin(denom1, 5000),
sdk.NewInt64Coin(denom2, 2500),
},
expectProceeds: []sdk.Coin{},
expectReverseCharge: true,
},
}

for _, c := range cases {
s.Run(c.name, func() {
s.SetupTest(true) // setup
require := s.Require()
tk := s.app.TreasuryKeeper
ak := s.app.AccountKeeper
bk := s.app.BankKeeper

burnTaxRate := sdk.NewDecWithPrec(5, 3)
burnSplitRate := sdk.NewDecWithPrec(5, 1)
oracleSplitRate := sdk.ZeroDec()

// Set burn split rate to 50%
tk.SetBurnSplitRate(s.ctx, burnSplitRate)
tk.SetOracleSplitRate(s.ctx, oracleSplitRate)

s.txBuilder = s.clientCtx.TxConfig.NewTxBuilder()

tk.AddBurnTaxExemptionAddress(s.ctx, addrs[0].String())
tk.AddBurnTaxExemptionAddress(s.ctx, addrs[1].String())

mfd := ante.NewFeeDecorator(s.app.AccountKeeper, s.app.BankKeeper, s.app.FeeGrantKeeper, s.app.TreasuryKeeper, s.app.DistrKeeper, s.app.TaxKeeper)
antehandler := sdk.ChainAnteDecorators(mfd)
pd := post.NewTaxDecorator(s.app.TaxKeeper, bk, ak, tk)
posthandler := sdk.ChainPostDecorators(pd)

// Fund accounts with both denoms
for i := 0; i < 4; i++ {
coins := sdk.NewCoins(
sdk.NewCoin(denom1, sdk.NewInt(10000000)),
sdk.NewCoin(denom2, sdk.NewInt(10000000)),
)
testutil.FundAccount(s.app.BankKeeper, s.ctx, addrs[i], coins)
}

// Set up transaction with multiple fee denoms
feeAmount := sdk.NewCoins(c.minFeeAmounts...)
gasLimit := testdata.NewTestGasLimit()
require.NoError(s.txBuilder.SetMsgs(c.msgCreator()...))
s.txBuilder.SetFeeAmount(feeAmount)
s.txBuilder.SetGasLimit(gasLimit)

privs, accNums, accSeqs := []cryptotypes.PrivKey{c.msgSigner}, []uint64{0}, []uint64{0}
tx, err := s.CreateTestTx(privs, accNums, accSeqs, s.ctx.ChainID())
require.NoError(err)

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

actualTaxRate := s.app.TaxKeeper.GetBurnTaxRate(s.ctx)
require.Equal(burnTaxRate, actualTaxRate)

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

// Check fee collector for each denom
feeCollector := ak.GetModuleAccount(s.ctx, authtypes.FeeCollectorName)
for _, feeCoin := range c.minFeeAmounts {
amountFee := bk.GetBalance(s.ctx, feeCollector.GetAddress(), feeCoin.Denom)
if c.expectReverseCharge {
require.Equal(amountFee, feeCoin)
} else {
expectedFee := sdk.NewCoin(
feeCoin.Denom,
sdk.NewDec(feeCoin.Amount.Int64()).Mul(burnSplitRate).TruncateInt(),
)
require.Equal(expectedFee, amountFee)
}
}

// Check tax proceeds
taxProceeds := s.app.TreasuryKeeper.PeekEpochTaxProceeds(s.ctx)
require.Equal(c.expectProceeds, taxProceeds)
})
}
}

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

0 comments on commit f48bef8

Please sign in to comment.