diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b39506b..9a25a456 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ Contains all the PRs that improved the code without changing the behaviours. ### Added +- [#422](https://github.com/archway-network/archway/pull/422/) - Add fee burning of tx fees not distributed to contracts. - [#419](https://github.com/archway-network/archway/pull/419) - Easily run localnet via make - [#421](https://github.com/archway-network/archway/pull/421) - Add archwayd darwin binaries diff --git a/app/ante.go b/app/ante.go index 91b78825..e1111173 100644 --- a/app/ante.go +++ b/app/ante.go @@ -22,8 +22,9 @@ import ( type HandlerOptions struct { ante.HandlerOptions - IBCKeeper *ibckeeper.Keeper - WasmConfig *wasmTypes.WasmConfig + IBCKeeper *ibckeeper.Keeper + WasmConfig *wasmTypes.WasmConfig + RewardsAnteBankKeeper rewardsAnte.BankKeeper TXCounterStoreKey sdk.StoreKey @@ -76,7 +77,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { // Custom Archway interceptor to track new transactions trackingAnte.NewTxGasTrackingDecorator(options.TrackingKeeper), // Custom Archway fee deduction, which splits fees between x/rewards and x/auth fee collector - rewardsAnte.NewDeductFeeDecorator(options.Codec, options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.RewardsKeeper), + rewardsAnte.NewDeductFeeDecorator(options.Codec, options.AccountKeeper, options.RewardsAnteBankKeeper, options.FeegrantKeeper, options.RewardsKeeper), // SetPubKeyDecorator must be called before all signature verification decorators ante.NewSetPubKeyDecorator(options.AccountKeeper), ante.NewValidateSigCountDecorator(options.AccountKeeper), diff --git a/app/app.go b/app/app.go index 12a525d5..ade6c126 100644 --- a/app/app.go +++ b/app/app.go @@ -225,7 +225,7 @@ var ( // module account permissions maccPerms = map[string][]string{ rewardsTypes.ContractRewardCollector: nil, - authtypes.FeeCollectorName: nil, + authtypes.FeeCollectorName: {authtypes.Burner}, distrtypes.ModuleName: nil, minttypes.ModuleName: {authtypes.Minter}, stakingtypes.BondedPoolName: {authtypes.Burner, authtypes.Staking}, @@ -799,11 +799,12 @@ func NewArchwayApp( SignModeHandler: encodingConfig.TxConfig.SignModeHandler(), SigGasConsumer: ante.DefaultSigVerificationGasConsumer, }, - IBCKeeper: app.IBCKeeper, - WasmConfig: &wasmConfig, - TXCounterStoreKey: keys[wasm.StoreKey], - TrackingKeeper: app.TrackingKeeper, - RewardsKeeper: app.RewardsKeeper, + IBCKeeper: app.IBCKeeper, + WasmConfig: &wasmConfig, + RewardsAnteBankKeeper: app.BankKeeper, + TXCounterStoreKey: keys[wasm.StoreKey], + TrackingKeeper: app.TrackingKeeper, + RewardsKeeper: app.RewardsKeeper, }, ) if err != nil { diff --git a/docs/adr/ADR-007-fee-burning.md b/docs/adr/ADR-007-fee-burning.md new file mode 100644 index 00000000..3f3653fa --- /dev/null +++ b/docs/adr/ADR-007-fee-burning.md @@ -0,0 +1,32 @@ +# ADR-007 – Introduction of fee burning + +Date: 2023-07-27 + +## Status + +Implemented + +## Context + +To better accommodate inflationary rewards increases within the Archway protocol, we are introducing transaction (TX) +fee burning. This strategy permits us to offer more inflationary rewards to contracts safely, while simultaneously +incinerating the TX fees which were previously distributed to validators and stakers. + +## Decision + +We plan to modify the Fee Deduction ante handler to burn the fees formerly allocated to validators and stakers. This +change involves extending the behavior of the FeeDeduction ante handler. Currently, the FeeDeduction ante handler +dispatches the TX fees (which are not dedicated to contracts) to the fee collector module address. +This address then becomes a rewards pool for staking rewards, managed by the Distribution module. Our new approach is to +burn these funds as soon as the FeeDeduction handler sends them to the fee collector. + +## Consequences + +### Positive +a) This change enables a safe increase of inflationary rewards for contracts, mitigating the risk of potential spam attacks and economic imbalances. +b) It establishes a transparent performance metric for Archway. The more fees burnt, the more value is generated for the protocol. + +### Negative + +a) Validators and stakers will experience a decrease in their rewards. +b) TX consume slightly more gas (12000gas more approximately), as they will need to pay for the gas used to burn the fees. diff --git a/e2e/txfees_test.go b/e2e/txfees_test.go index 7078b4bf..249a907f 100644 --- a/e2e/txfees_test.go +++ b/e2e/txfees_test.go @@ -20,7 +20,7 @@ import ( // Test configures a chain based on the Archway mainnet parameters. func (s *E2ETestSuite) TestTxFees() { const ( - txGasLimit = 201_000 + txGasLimit = 212_000 txFeeAmtIncrement = 1000 ) diff --git a/x/rewards/ante/fee_deduction.go b/x/rewards/ante/fee_deduction.go index af31383a..cb82a70a 100644 --- a/x/rewards/ante/fee_deduction.go +++ b/x/rewards/ante/fee_deduction.go @@ -15,6 +15,11 @@ import ( var _ sdk.AnteDecorator = DeductFeeDecorator{} +type BankKeeper interface { + authTypes.BankKeeper + BurnCoins(ctx sdk.Context, moduleName string, amt sdk.Coins) error +} + // DeductFeeDecorator deducts fees from the first signer of the tx. // If the first signer does not have the funds to pay for the fees, return with InsufficientFunds error. // Call next AnteHandler if fees successfully deducted. @@ -22,13 +27,13 @@ var _ sdk.AnteDecorator = DeductFeeDecorator{} type DeductFeeDecorator struct { codec codec.BinaryCodec ak ante.AccountKeeper - bankKeeper authTypes.BankKeeper + bankKeeper BankKeeper feegrantKeeper ante.FeegrantKeeper rewardsKeeper RewardsKeeperExpected } // NewDeductFeeDecorator returns a new DeductFeeDecorator instance. -func NewDeductFeeDecorator(codec codec.BinaryCodec, ak ante.AccountKeeper, bk authTypes.BankKeeper, fk ante.FeegrantKeeper, rk RewardsKeeperExpected) DeductFeeDecorator { +func NewDeductFeeDecorator(codec codec.BinaryCodec, ak ante.AccountKeeper, bk BankKeeper, fk ante.FeegrantKeeper, rk RewardsKeeperExpected) DeductFeeDecorator { return DeductFeeDecorator{ codec: codec, ak: ak, @@ -138,6 +143,10 @@ func (dfd DeductFeeDecorator) deductFees(ctx sdk.Context, tx sdk.Tx, acc authTyp if err := dfd.bankKeeper.SendCoinsFromAccountToModule(ctx, acc.GetAddress(), authTypes.FeeCollectorName, authFees); err != nil { return sdkErrors.Wrapf(sdkErrors.ErrInsufficientFunds, err.Error()) } + // burn the auth fees. + if err := dfd.bankKeeper.BurnCoins(ctx, authTypes.FeeCollectorName, authFees); err != nil { + return sdkErrors.Wrapf(sdkErrors.ErrInsufficientFunds, err.Error()) + } } if !rewardsFees.Empty() { diff --git a/x/rewards/ante/fee_deduction_test.go b/x/rewards/ante/fee_deduction_test.go index 9384d7c2..8c8bde39 100644 --- a/x/rewards/ante/fee_deduction_test.go +++ b/x/rewards/ante/fee_deduction_test.go @@ -54,7 +54,7 @@ func TestRewardsFeeDeductionAnteHandler(t *testing.T) { mockWasmExecuteMsg, }, rewardRecordExpected: true, - feeCollectorBalanceDiffExpected: "500stake", + feeCollectorBalanceDiffExpected: "0stake", // fees are burnt rewardsBalanceDiffExpected: "500stake", }, { @@ -66,7 +66,7 @@ func TestRewardsFeeDeductionAnteHandler(t *testing.T) { mockWasmExecuteMsg, }, rewardRecordExpected: true, - feeCollectorBalanceDiffExpected: "900stake,450uarch", + feeCollectorBalanceDiffExpected: "0stake,0uarch", // fees are burnt rewardsBalanceDiffExpected: "100stake,50uarch", }, {