github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/feesplit/keeper/evm_hooks.go (about)

     1  package keeper
     2  
     3  import (
     4  	"math/big"
     5  
     6  	ethtypes "github.com/ethereum/go-ethereum/core/types"
     7  
     8  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     9  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    10  	evmtypes "github.com/fibonacci-chain/fbc/x/evm/types"
    11  	"github.com/fibonacci-chain/fbc/x/feesplit/types"
    12  )
    13  
    14  var _ evmtypes.EvmHooks = Hooks{}
    15  
    16  // Hooks wrapper struct for fees keeper
    17  type Hooks struct {
    18  	k Keeper
    19  }
    20  
    21  // Hooks return the wrapper hooks struct for the Keeper
    22  func (k Keeper) Hooks() Hooks {
    23  	return Hooks{k}
    24  }
    25  
    26  // PostTxProcessing is a wrapper for calling the EVM PostTxProcessing hook on
    27  // the module keeper
    28  func (h Hooks) PostTxProcessing(ctx sdk.Context, st *evmtypes.StateTransition, receipt *ethtypes.Receipt) error {
    29  	return h.k.PostTxProcessing(ctx, st, receipt)
    30  }
    31  
    32  // PostTxProcessing implements EvmHooks.PostTxProcessing. After each successful
    33  // interaction with a registered contract, the contract deployer (or, if set,
    34  // the withdraw address) receives a share from the transaction fees paid by the
    35  // transaction sender.
    36  func (k Keeper) PostTxProcessing(
    37  	ctx sdk.Context,
    38  	st *evmtypes.StateTransition,
    39  	receipt *ethtypes.Receipt,
    40  ) error {
    41  	// This is different from ibc and wasm, evm tx exists at all times.
    42  	// in Venus3 height store takes effect,
    43  	// in Venus3+1 height initGenesis takes effect,
    44  	// in Venus3+2 height can be used normally params
    45  	if !tmtypes.HigherThanVenus3(ctx.BlockHeight() - 1) {
    46  		return nil
    47  	}
    48  
    49  	// For GetParams using cache, no fee is charged
    50  	currentGasMeter := ctx.GasMeter()
    51  	infGasMeter := sdk.GetReusableInfiniteGasMeter()
    52  	ctx.SetGasMeter(infGasMeter)
    53  	defer func() {
    54  		ctx.SetGasMeter(currentGasMeter)
    55  		sdk.ReturnInfiniteGasMeter(infGasMeter)
    56  	}()
    57  
    58  	// check if the fees are globally enabled
    59  	params := k.GetParamsWithCache(ctx)
    60  	if !params.EnableFeeSplit {
    61  		return nil
    62  	}
    63  
    64  	contract := st.Recipient
    65  	if contract == nil {
    66  		return nil
    67  	}
    68  
    69  	// if the contract is not registered to receive fees, do nothing
    70  	feeSplit, found := k.GetFeeSplitWithCache(ctx, *contract)
    71  	if !found {
    72  		return nil
    73  	}
    74  
    75  	withdrawer := feeSplit.WithdrawerAddress
    76  	if withdrawer.Empty() {
    77  		withdrawer = feeSplit.DeployerAddress
    78  	}
    79  
    80  	developerShares := params.DeveloperShares
    81  	// if the contract shares is set by proposal
    82  	shares, found := k.GetContractShareWithCache(ctx, *contract)
    83  	if found {
    84  		developerShares = shares
    85  	}
    86  	if developerShares.LTE(sdk.ZeroDec()) {
    87  		return nil
    88  	}
    89  
    90  	txFee := new(big.Int).Mul(st.Price, new(big.Int).SetUint64(currentGasMeter.GasConsumed()))
    91  	developerFee := sdk.NewDecFromBigIntWithPrec(txFee, sdk.Precision).Mul(developerShares)
    92  	if developerFee.LTE(sdk.ZeroDec()) {
    93  		return nil
    94  	}
    95  	fees := sdk.Coins{{Denom: sdk.DefaultBondDenom, Amount: developerFee}}
    96  
    97  	//distribute the fees to the contract deployer / withdraw address
    98  	f := ctx.GetFeeSplitInfo()
    99  	f.Addr = withdrawer
   100  	f.Fee = fees
   101  	f.HasFee = true
   102  
   103  	// add innertx
   104  	k.addFeesplitInnerTx(receipt.TxHash.Hex(), withdrawer.String(), fees.String())
   105  
   106  	ctx.EventManager().EmitEvents(
   107  		sdk.Events{
   108  			sdk.NewEvent(
   109  				types.EventTypeDistributeDevFeeSplit,
   110  				sdk.NewAttribute(sdk.AttributeKeySender, st.Sender.String()),
   111  				sdk.NewAttribute(types.AttributeKeyContract, contract.String()),
   112  				sdk.NewAttribute(types.AttributeKeyWithdrawerAddress, withdrawer.String()),
   113  				sdk.NewAttribute(sdk.AttributeKeyAmount, developerFee.String()),
   114  			),
   115  		},
   116  	)
   117  
   118  	return nil
   119  }