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 }