Skip to content

Commit

Permalink
test(v2.9): burn unused tx fees
Browse files Browse the repository at this point in the history
  • Loading branch information
emidev98 committed Dec 15, 2023
1 parent 60068e6 commit 85fe7dd
Show file tree
Hide file tree
Showing 10 changed files with 435 additions and 35 deletions.
4 changes: 4 additions & 0 deletions app/app_test/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/stretchr/testify/suite"
terra_app "github.com/terra-money/core/v2/app"
appparams "github.com/terra-money/core/v2/app/params"
feeburntypes "github.com/terra-money/core/v2/x/feeburn/types"
feesharetypes "github.com/terra-money/core/v2/x/feeshare/types"
tokenfactorytypes "github.com/terra-money/core/v2/x/tokenfactory/types"

Expand Down Expand Up @@ -80,6 +81,9 @@ func (s *AppTestSuite) Setup() {
err = s.App.Keepers.TokenFactoryKeeper.SetParams(s.Ctx, tokenfactorytypes.DefaultParams())
s.Require().NoError(err)

err = s.App.Keepers.FeeBurnKeeper.SetParams(s.Ctx, feeburntypes.DefaultParams())
s.Require().NoError(err)

err = s.FundModule(authtypes.FeeCollectorName, sdk.NewCoins(sdk.NewCoin("uluna", sdk.NewInt(1000)), sdk.NewCoin("utoken", sdk.NewInt(500))))
s.Require().NoError(err)

Expand Down
5 changes: 5 additions & 0 deletions app/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ func TestGenesis(t *testing.T) {
"evidence": {
"evidence": []
},
"feeburn": {
"params": {
"enable_fee_burn": true
}
},
"feegrant": {
"allowances": []
},
Expand Down
14 changes: 7 additions & 7 deletions integration-tests/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"typescript": "^5.2.2"
},
"dependencies": {
"@terra-money/feather.js": "^2.0.0-beta.15",
"@terra-money/feather.js": "^2.0.0-beta.16",
"moment": "^2.29.4"
}
}
57 changes: 57 additions & 0 deletions integration-tests/src/modules/feeburn/feeburn.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Coins, Fee, MnemonicKey, MsgSend } from "@terra-money/feather.js";
import { getMnemonics, getLCDClient, blockInclusion } from "../../helpers";

describe("FeeBurn Module (https://github.com/terra-money/core/tree/release/v2.9/x/feeburn) ", () => {
// Prepare environment clients, accounts and wallets
const LCD = getLCDClient();
const accounts = getMnemonics();
const wallet = LCD.chain1.wallet(accounts.mnemonic2);
const randomAddress = new MnemonicKey().accAddress("terra");

test('Must burn unused TX Fees', async () => {
try {
const sendTx = await wallet.createAndSignTx({
msgs: [new MsgSend(
wallet.key.accAddress("terra"),
randomAddress,
new Coins({ uluna: 1 }),
)],
chainID: "test-1",
fee: new Fee(200_000, new Coins({ uluna: 3_000 })),
});

const result = await LCD.chain1.tx.broadcastSync(sendTx, "test-1");
await blockInclusion();
const txResult = await LCD.chain1.tx.txInfo(result.txhash, "test-1");
const eventsLength = txResult.events.length;
expect([txResult.events[eventsLength - 2], txResult.events[eventsLength - 1]])
.toStrictEqual([{
"type": "burn",
"attributes": [{
"key": "burner",
"value": "terra17xpfvakm2amg962yls6f84z3kell8c5lkaeqfa",
"index": true
}, {
"key": "amount",
"value": "1231uluna",
"index": true
}]
}, {
"type": "terra.feeburn.v1.FeeBurnEvent",
"attributes": [{
"key": "burn_rate",
"value": "\"0.410385000000000000\"",
"index": true
}, {
"key": "fees_burn",
"value": "[{\"denom\":\"uluna\",\"amount\":\"1231\"}]",
"index": true
}]
}]);

}
catch (e) {
console.log(e)
}
});
});
File renamed without changes.
8 changes: 6 additions & 2 deletions proto/terra/feeburn/v1/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ option go_package = "github.com/terra-money/core/v2/x/feeburn/types";

// Event fired when fees are burned with the amount of fees burned
message FeeBurnEvent {
// Amount of the payout
repeated cosmos.base.v1beta1.Coin fees_burn = 1 [
// Amount of the payout
repeated cosmos.base.v1beta1.Coin fees_burn = 1 [(gogoproto.nullable) = false];

// Calculated % of the fees burned before truncating the decimal
string burn_rate = 2 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec",
(gogoproto.nullable) = false
];
}
31 changes: 22 additions & 9 deletions x/feeburn/post/post.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package post

import (
"fmt"

errorsmod "cosmossdk.io/errors"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -18,9 +20,9 @@ func NewFeeBurnDecorator(feeBurnKeeper FeeBurnKeeper, bankkeeper BankKeeper) Fee
return FeeBurnDecorator{feeBurnKeeper, bankkeeper}
}

func (bd FeeBurnDecorator) PostHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, success bool, next sdk.PostHandler) (newCtx sdk.Context, err error) {
func (fbd FeeBurnDecorator) PostHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, success bool, next sdk.PostHandler) (newCtx sdk.Context, err error) {
// if the feeburn is not enabled then just continue with the next decorator
if !bd.feeBurnKeeper.GetParams(ctx).EnableFeeBurn {
if !fbd.feeBurnKeeper.GetParams(ctx).EnableFeeBurn {
return next(ctx, tx, simulate, success)
}

Expand Down Expand Up @@ -48,23 +50,28 @@ func (bd FeeBurnDecorator) PostHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,
return next(ctx, tx, simulate, success)
}
gasLimit := math.LegacyNewDecFromInt(sdk.NewInt(int64(gasMeter.Limit())))
remainingGas := math.LegacyNewDecFromInt(sdk.NewInt(int64(gasMeter.GasRemaining())))
remainingGas := math.LegacyNewDecFromInt(sdk.NewInt(int64(gasMeter.GasConsumed())))
// Percentage of unused gas for this specific denom
burnRate := remainingGas.Quo(gasLimit)
fmt.Printf("remainingGas: %s\n", remainingGas)
fmt.Printf("gasLimit: %s\n", gasLimit)
fmt.Printf("burnRate: %s\n", burnRate)

var toBurn sdk.Coins
// Iterate over the transaction fees and calculate the proportional part
// of the unused fees denominated in the tokens used to pay fo the fees
// and add it to the toBurn variable that will be sent to the user.
for _, txFee := range txFees {
// Percentage of unused gas for this specific denom
remainingGasProportion := remainingGas.Quo(gasLimit)

// Given the percentage of unused gas, calculate the
// proportional part of the fees that will be refunded
// to the user in this specific denom.
unusedFees := math.LegacyNewDecFromInt(txFee.Amount).
Mul(remainingGasProportion).
Mul(burnRate).
TruncateInt()

fmt.Printf("math.LegacyNewDecFromInt(txFee.Amount) %s\n", math.LegacyNewDecFromInt(txFee.Amount))

// When the unused fees are positive it means that the user
// will receive a refund in this specific denom to its wallet.
if unusedFees.IsPositive() {
Expand All @@ -77,17 +84,23 @@ func (bd FeeBurnDecorator) PostHandle(ctx sdk.Context, tx sdk.Tx, simulate bool,

// Execute the refund to the user, if there is an error
// return the error otherwise continue with the execution
err = bd.bankkeeper.BurnCoins(ctx, authtypes.FeeCollectorName, toBurn)
err = fbd.bankkeeper.BurnCoins(ctx, authtypes.FeeCollectorName, toBurn)
if err != nil {
return ctx, err
}

// Emit an event to be able to track the fees burned
// because there can be a little bit of discrepancy
// between fees used and burned, because the proportional
// part of the fees is truncated to an integer.
err = ctx.EventManager().EmitTypedEvent(
&types.FeeBurnEvent{FeesBurn: toBurn},
&types.FeeBurnEvent{
FeesBurn: toBurn,
BurnRate: burnRate,
},
)
if err != nil {
return ctx, err
}

return next(ctx, tx, simulate, success)
}
Loading

0 comments on commit 85fe7dd

Please sign in to comment.