From 9957dd330c10ef8dcd331161ef8bdca04b9641cc Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Wed, 29 Jan 2025 00:34:23 +0100 Subject: [PATCH] chore(wallet)_: adjusting fees calculation to get closer to MM values --- .../connector/commands/send_transaction.go | 4 +- .../commands/send_transaction_test.go | 9 ++- services/connector/connector_flows_test.go | 3 +- services/wallet/router/fees/fees.go | 80 ++++++++++++++----- services/wallet/router/fees/fees_test.go | 35 +++++--- .../wallet/router/fees/suggested_priority.go | 69 +++++++++++++--- services/wallet/router/router_helper.go | 14 ++-- tests-functional/utils/wallet_utils.py | 37 +++++++-- 8 files changed, 191 insertions(+), 60 deletions(-) diff --git a/services/connector/commands/send_transaction.go b/services/connector/commands/send_transaction.go index 9ed836d972f..fe5be2daa87 100644 --- a/services/connector/commands/send_transaction.go +++ b/services/connector/commands/send_transaction.go @@ -97,12 +97,12 @@ func (c *SendTransactionCommand) Execute(ctx context.Context, request RPCRequest if !fetchedFees.EIP1559Enabled { params.GasPrice = (*hexutil.Big)(fetchedFees.GasPrice) } else { - maxFees, err := fetchedFees.FeeFor(fees.GasFeeMedium) + maxFees, priorityFee, err := fetchedFees.FeeFor(fees.GasFeeMedium) if err != nil { return "", err } params.MaxFeePerGas = (*hexutil.Big)(maxFees) - params.MaxPriorityFeePerGas = (*hexutil.Big)(fetchedFees.MaxPriorityFeePerGas) + params.MaxPriorityFeePerGas = (*hexutil.Big)(priorityFee) } } diff --git a/services/connector/commands/send_transaction_test.go b/services/connector/commands/send_transaction_test.go index f13fc393260..c8fdaf9e662 100644 --- a/services/connector/commands/send_transaction_test.go +++ b/services/connector/commands/send_transaction_test.go @@ -83,7 +83,8 @@ func TestSendTransactionWithSignalTimout(t *testing.T) { mockedChainClient := mock_client.NewMockClientInterface(state.mockCtrl) feeHistory := &fees.FeeHistory{} - state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(300), "latest", []int{25, 50, 75}).Times(1).Return(nil) + percentiles := []int{fees.RewardPercentiles1, fees.RewardPercentiles2, fees.RewardPercentiles3} + state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil) state.rpcClient.EXPECT().EthClient(uint64(1)).Times(1).Return(mockedChainClient, nil) mockedChainClient.EXPECT().SuggestGasPrice(state.ctx).Times(1).Return(big.NewInt(1), nil) state.rpcClient.EXPECT().EthClient(uint64(1)).Times(1).Return(mockedChainClient, nil) @@ -129,7 +130,8 @@ func TestSendTransactionWithSignalAccepted(t *testing.T) { mockedChainClient := mock_client.NewMockClientInterface(state.mockCtrl) feeHistory := &fees.FeeHistory{} - state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(300), "latest", []int{25, 50, 75}).Times(1).Return(nil) + percentiles := []int{fees.RewardPercentiles1, fees.RewardPercentiles2, fees.RewardPercentiles3} + state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil) state.rpcClient.EXPECT().EthClient(uint64(1)).Times(1).Return(mockedChainClient, nil) mockedChainClient.EXPECT().SuggestGasPrice(state.ctx).Times(1).Return(big.NewInt(1), nil) state.rpcClient.EXPECT().EthClient(uint64(1)).Times(1).Return(mockedChainClient, nil) @@ -172,7 +174,8 @@ func TestSendTransactionWithSignalRejected(t *testing.T) { mockedChainClient := mock_client.NewMockClientInterface(state.mockCtrl) feeHistory := &fees.FeeHistory{} - state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(300), "latest", []int{25, 50, 75}).Times(1).Return(nil) + percentiles := []int{fees.RewardPercentiles1, fees.RewardPercentiles2, fees.RewardPercentiles3} + state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil) state.rpcClient.EXPECT().EthClient(uint64(1)).Times(1).Return(mockedChainClient, nil) mockedChainClient.EXPECT().SuggestGasPrice(state.ctx).Times(1).Return(big.NewInt(1), nil) state.rpcClient.EXPECT().EthClient(uint64(1)).Times(1).Return(mockedChainClient, nil) diff --git a/services/connector/connector_flows_test.go b/services/connector/connector_flows_test.go index 2fb908336c8..7732f89a048 100644 --- a/services/connector/connector_flows_test.go +++ b/services/connector/connector_flows_test.go @@ -105,7 +105,8 @@ func TestRequestAccountsSwitchChainAndSendTransactionFlow(t *testing.T) { // Send transaction mockedChainClient := mock_client.NewMockClientInterface(state.mockCtrl) feeHistory := &fees.FeeHistory{} - state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(300), "latest", []int{25, 50, 75}).Times(1).Return(nil) + percentiles := []int{fees.RewardPercentiles1, fees.RewardPercentiles2, fees.RewardPercentiles3} + state.rpcClient.EXPECT().Call(feeHistory, uint64(1), "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil) state.rpcClient.EXPECT().EthClient(uint64(1)).Times(1).Return(mockedChainClient, nil) mockedChainClient.EXPECT().SuggestGasPrice(state.ctx).Times(1).Return(big.NewInt(1), nil) state.rpcClient.EXPECT().EthClient(uint64(1)).Times(1).Return(mockedChainClient, nil) diff --git a/services/wallet/router/fees/fees.go b/services/wallet/router/fees/fees.go index 0475a4025b4..ab1d26515c9 100644 --- a/services/wallet/router/fees/fees.go +++ b/services/wallet/router/fees/fees.go @@ -10,6 +10,12 @@ import ( "github.com/status-im/status-go/services/wallet/common" ) +const ( + RewardPercentiles1 = 10 + RewardPercentiles2 = 50 + RewardPercentiles3 = 90 +) + type GasFeeMode int const ( @@ -26,9 +32,12 @@ var ( ) type MaxFeesLevels struct { - Low *hexutil.Big `json:"low"` - Medium *hexutil.Big `json:"medium"` - High *hexutil.Big `json:"high"` + Low *hexutil.Big `json:"low"` + LowPriority *hexutil.Big `json:"lowPriority"` + Medium *hexutil.Big `json:"medium"` + MediumPriority *hexutil.Big `json:"mediumPriority"` + High *hexutil.Big `json:"high"` + HighPriority *hexutil.Big `json:"highPriority"` } type MaxPriorityFeesSuggestedBounds struct { @@ -41,7 +50,7 @@ type SuggestedFees struct { BaseFee *big.Int CurrentBaseFee *big.Int // Current network base fee (in ETH WEI) MaxFeesLevels *MaxFeesLevels - MaxPriorityFeePerGas *big.Int + MaxPriorityFeePerGas *big.Int // TODO: remove once clients stop using this field MaxPriorityFeeSuggestedBounds *MaxPriorityFeesSuggestedBounds L1GasFee *big.Float EIP1559Enabled bool @@ -62,23 +71,23 @@ type SuggestedFeesGwei struct { EIP1559Enabled bool `json:"eip1559Enabled"` } -func (m *MaxFeesLevels) FeeFor(mode GasFeeMode) (*big.Int, error) { +func (m *MaxFeesLevels) FeeFor(mode GasFeeMode) (*big.Int, *big.Int, error) { if mode == GasFeeCustom { - return nil, ErrCustomFeeModeNotAvailableInSuggestedFees + return nil, nil, ErrCustomFeeModeNotAvailableInSuggestedFees } if mode == GasFeeLow { - return m.Low.ToInt(), nil + return m.Low.ToInt(), m.LowPriority.ToInt(), nil } if mode == GasFeeHigh { - return m.High.ToInt(), nil + return m.High.ToInt(), m.HighPriority.ToInt(), nil } - return m.Medium.ToInt(), nil + return m.Medium.ToInt(), m.MediumPriority.ToInt(), nil } -func (s *SuggestedFees) FeeFor(mode GasFeeMode) (*big.Int, error) { +func (s *SuggestedFees) FeeFor(mode GasFeeMode) (*big.Int, *big.Int, error) { return s.MaxFeesLevels.FeeFor(mode) } @@ -87,32 +96,61 @@ type FeeManager struct { } func (f *FeeManager) SuggestedFees(ctx context.Context, chainID uint64) (*SuggestedFees, error) { - feeHistory, err := f.getFeeHistory(ctx, chainID, 300, "latest", []int{25, 50, 75}) + feeHistory, err := f.getFeeHistory(ctx, chainID, 300, "latest", []int{RewardPercentiles1, RewardPercentiles2, RewardPercentiles3}) if err != nil { return f.getNonEIP1559SuggestedFees(ctx, chainID) } - maxPriorityFeePerGasLowerBound, maxPriorityFeePerGas, maxPriorityFeePerGasUpperBound, baseFee, err := getEIP1559SuggestedFees(feeHistory) + lowPriorityFeePerGasLowerBound, mediumPriorityFeePerGas, maxPriorityFeePerGasUpperBound, baseFee, err := getEIP1559SuggestedFees(feeHistory) if err != nil { return f.getNonEIP1559SuggestedFees(ctx, chainID) } - return &SuggestedFees{ + suggestedFees := &SuggestedFees{ GasPrice: big.NewInt(0), BaseFee: baseFee, CurrentBaseFee: baseFee, - MaxPriorityFeePerGas: maxPriorityFeePerGas, + MaxPriorityFeePerGas: mediumPriorityFeePerGas, MaxPriorityFeeSuggestedBounds: &MaxPriorityFeesSuggestedBounds{ - Lower: maxPriorityFeePerGasLowerBound, + Lower: lowPriorityFeePerGasLowerBound, Upper: maxPriorityFeePerGasUpperBound, }, - MaxFeesLevels: &MaxFeesLevels{ - Low: (*hexutil.Big)(new(big.Int).Add(baseFee, maxPriorityFeePerGas)), - Medium: (*hexutil.Big)(new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(2)), maxPriorityFeePerGas)), - High: (*hexutil.Big)(new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(3)), maxPriorityFeePerGas)), - }, EIP1559Enabled: true, - }, nil + } + + if chainID == common.EthereumMainnet || chainID == common.EthereumSepolia || chainID == common.AnvilMainnet { + networkCongestion := calculateNetworkCongestion(feeHistory) + + baseFeeFloat := new(big.Float).SetUint64(baseFee.Uint64()) + baseFeeFloat.Mul(baseFeeFloat, big.NewFloat(networkCongestion)) + additionBasedOnCongestion := new(big.Int) + baseFeeFloat.Int(additionBasedOnCongestion) + + mediumBaseFee := new(big.Int).Add(baseFee, additionBasedOnCongestion) + + highBaseFee := new(big.Int).Mul(baseFee, big.NewInt(2)) + highBaseFee.Add(highBaseFee, additionBasedOnCongestion) + + suggestedFees.MaxFeesLevels = &MaxFeesLevels{ + Low: (*hexutil.Big)(new(big.Int).Add(baseFee, lowPriorityFeePerGasLowerBound)), + LowPriority: (*hexutil.Big)(lowPriorityFeePerGasLowerBound), + Medium: (*hexutil.Big)(new(big.Int).Add(mediumBaseFee, mediumPriorityFeePerGas)), + MediumPriority: (*hexutil.Big)(mediumPriorityFeePerGas), + High: (*hexutil.Big)(new(big.Int).Add(highBaseFee, maxPriorityFeePerGasUpperBound)), + HighPriority: (*hexutil.Big)(maxPriorityFeePerGasUpperBound), + } + } else { + suggestedFees.MaxFeesLevels = &MaxFeesLevels{ + Low: (*hexutil.Big)(new(big.Int).Add(baseFee, lowPriorityFeePerGasLowerBound)), + LowPriority: (*hexutil.Big)(lowPriorityFeePerGasLowerBound), + Medium: (*hexutil.Big)(new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(4)), mediumPriorityFeePerGas)), + MediumPriority: (*hexutil.Big)(mediumPriorityFeePerGas), + High: (*hexutil.Big)(new(big.Int).Add(new(big.Int).Mul(baseFee, big.NewInt(10)), maxPriorityFeePerGasUpperBound)), + HighPriority: (*hexutil.Big)(maxPriorityFeePerGasUpperBound), + } + } + + return suggestedFees, nil } // ////////////////////////////////////////////////////////////////////////////// diff --git a/services/wallet/router/fees/fees_test.go b/services/wallet/router/fees/fees_test.go index cbcaa09dab3..0781865daec 100644 --- a/services/wallet/router/fees/fees_test.go +++ b/services/wallet/router/fees/fees_test.go @@ -70,8 +70,8 @@ func TestSuggestedFeesForNotEIP1559CompatibleChains(t *testing.T) { chainID := uint64(1) gasPrice := big.NewInt(1) feeHistory := &FeeHistory{} - - state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(300), "latest", []int{25, 50, 75}).Times(1).Return(nil) + percentiles := []int{RewardPercentiles1, RewardPercentiles2, RewardPercentiles3} + state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil) mockedChainClient := mock_client.NewMockClientInterface(state.mockCtrl) state.rpcClient.EXPECT().EthClient(chainID).Times(1).Return(mockedChainClient, nil) mockedChainClient.EXPECT().SuggestGasPrice(state.ctx).Times(1).Return(gasPrice, nil) @@ -88,8 +88,8 @@ func TestSuggestedFeesForEIP1559CompatibleChains(t *testing.T) { chainID := uint64(1) feeHistory := &FeeHistory{} - - state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(300), "latest", []int{25, 50, 75}).Times(1).Return(nil). + percentiles := []int{RewardPercentiles1, RewardPercentiles2, RewardPercentiles3} + state.rpcClient.EXPECT().Call(feeHistory, chainID, "eth_feeHistory", uint64(300), "latest", percentiles).Times(1).Return(nil). Do(func(feeHistory, chainID, method any, args ...any) { feeHistoryResponse := &FeeHistory{ BaseFeePerGas: []string{ @@ -156,14 +156,25 @@ func TestSuggestedFeesForEIP1559CompatibleChains(t *testing.T) { assert.NoError(t, err) assert.NotNil(t, suggestedFees) + variadicFee1 := big.NewInt(0).Sub(suggestedFees.MaxFeesLevels.High.ToInt(), suggestedFees.MaxFeesLevels.HighPriority.ToInt()) + variadicFee1.Sub(variadicFee1, big.NewInt(0).Mul(big.NewInt(2), suggestedFees.BaseFee)) + + variadicFee2 := big.NewInt(0).Sub(suggestedFees.MaxFeesLevels.Medium.ToInt(), suggestedFees.MaxFeesLevels.MediumPriority.ToInt()) + variadicFee2.Sub(variadicFee2, suggestedFees.BaseFee) + + assert.Equal(t, variadicFee1, variadicFee2) + assert.Equal(t, big.NewInt(0), suggestedFees.GasPrice) - assert.Equal(t, big.NewInt(6958609414), suggestedFees.BaseFee) - assert.Equal(t, big.NewInt(6958609414), suggestedFees.CurrentBaseFee) - assert.Equal(t, big.NewInt(7928609414), suggestedFees.MaxFeesLevels.Low.ToInt()) - assert.Equal(t, big.NewInt(14887218828), suggestedFees.MaxFeesLevels.Medium.ToInt()) - assert.Equal(t, big.NewInt(21845828242), suggestedFees.MaxFeesLevels.High.ToInt()) - assert.Equal(t, big.NewInt(970000000), suggestedFees.MaxPriorityFeePerGas) - assert.Equal(t, big.NewInt(54715554), suggestedFees.MaxPriorityFeeSuggestedBounds.Lower) - assert.Equal(t, big.NewInt(1636040877), suggestedFees.MaxPriorityFeeSuggestedBounds.Upper) + assert.Equal(t, big.NewInt(5362838082), suggestedFees.BaseFee) + assert.Equal(t, big.NewInt(5362838082), suggestedFees.CurrentBaseFee) + assert.Equal(t, big.NewInt(5462838082), suggestedFees.MaxFeesLevels.Low.ToInt()) + assert.Equal(t, big.NewInt(100000000), suggestedFees.MaxFeesLevels.LowPriority.ToInt()) + assert.Equal(t, big.NewInt(7795989313), suggestedFees.MaxFeesLevels.Medium.ToInt()) + assert.Equal(t, big.NewInt(970000000), suggestedFees.MaxFeesLevels.MediumPriority.ToInt()) + assert.Equal(t, big.NewInt(14104411640), suggestedFees.MaxFeesLevels.High.ToInt()) + assert.Equal(t, big.NewInt(1915584245), suggestedFees.MaxFeesLevels.HighPriority.ToInt()) + assert.Equal(t, suggestedFees.MaxFeesLevels.MediumPriority.ToInt(), suggestedFees.MaxPriorityFeePerGas) + assert.Equal(t, big.NewInt(100000000), suggestedFees.MaxPriorityFeeSuggestedBounds.Lower) + assert.Equal(t, big.NewInt(1915584245), suggestedFees.MaxPriorityFeeSuggestedBounds.Upper) assert.True(t, suggestedFees.EIP1559Enabled) } diff --git a/services/wallet/router/fees/suggested_priority.go b/services/wallet/router/fees/suggested_priority.go index aeb4d0f82f8..3d328f20387 100644 --- a/services/wallet/router/fees/suggested_priority.go +++ b/services/wallet/router/fees/suggested_priority.go @@ -10,7 +10,13 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" ) -const baseFeeIncreaseFactor = 1.33 +const ( + // To get closer to MM values, we don't want to increase the base fee + baseFeeIncreaseFactor = 1.025 // 2.5% increase + + priorityWeight = 0.7 + gasUsedWeight = 0.3 +) func hexStringToBigInt(value string) (*big.Int, error) { valueWitoutPrefix := strings.TrimPrefix(value, "0x") @@ -26,11 +32,14 @@ func scaleBaseFeePerGas(value string) (*big.Int, error) { if err != nil { return nil, err } - valueDouble := new(big.Float).SetInt(val) - valueDouble.Mul(valueDouble, big.NewFloat(baseFeeIncreaseFactor)) - scaledValue := new(big.Int) - valueDouble.Int(scaledValue) - return scaledValue, nil + if baseFeeIncreaseFactor > 0 { + valueDouble := new(big.Float).SetInt(val) + valueDouble.Mul(valueDouble, big.NewFloat(baseFeeIncreaseFactor)) + scaledValue := new(big.Int) + valueDouble.Int(scaledValue) + return scaledValue, nil + } + return val, nil } func (f *FeeManager) getNonEIP1559SuggestedFees(ctx context.Context, chainID uint64) (*SuggestedFees, error) { @@ -108,7 +117,7 @@ func getEIP1559SuggestedFees(feeHistory *FeeHistory) (lowPriorityFee, avgPriorit return currentPriorityFees[a].Cmp(currentPriorityFees[b]) < 0 }) - percentileIndex := int(float64(len(currentPriorityFees)) * 0.4) + percentileIndex := int(float64(len(currentPriorityFees)) * 0.5) if i == 0 { lowPriorityFee = currentPriorityFees[percentileIndex] } else if i == 1 { @@ -121,14 +130,14 @@ func getEIP1559SuggestedFees(feeHistory *FeeHistory) (lowPriorityFee, avgPriorit } // Adjust low priority fee if it's equal to avg - lowIndex := int(float64(len(priorityFees[0])) * 0.4) + lowIndex := int(float64(len(priorityFees[0])) * 0.5) for lowIndex > 0 && lowPriorityFee == avgPriorityFee { lowIndex-- lowPriorityFee = priorityFees[0][lowIndex] } // Adjust high priority fee if it's equal to avg - highIndex := int(float64(len(priorityFees[2])) * 0.4) + highIndex := int(float64(len(priorityFees[2])) * 0.5) for highIndex < len(priorityFees[2])-1 && highPriorityFee == avgPriorityFee { highIndex++ highPriorityFee = priorityFees[2][highIndex] @@ -136,3 +145,45 @@ func getEIP1559SuggestedFees(feeHistory *FeeHistory) (lowPriorityFee, avgPriorit return lowPriorityFee, avgPriorityFee, highPriorityFee, suggestedBaseFee, nil } + +func calculateNetworkCongestion(feeHistory *FeeHistory) float64 { + if len(feeHistory.BaseFeePerGas) == 0 || len(feeHistory.Reward) == 0 || len(feeHistory.GasUsedRatio) == 0 { + return 0.0 + } + + var totalBaseFee uint64 + for _, baseFee := range feeHistory.BaseFeePerGas { + fee, err := hexStringToBigInt(baseFee) + if err != nil { + return 0.0 + } + totalBaseFee = totalBaseFee + fee.Uint64() + } + avgBaseFee := float64(totalBaseFee) / float64(len(feeHistory.BaseFeePerGas)) + + var totalPriorityFee uint64 + var countPriorityFees int + for _, rewardSet := range feeHistory.Reward { + for _, reward := range rewardSet { + fee, err := hexStringToBigInt(reward) + if err != nil { + return 0.0 + } + totalPriorityFee = totalPriorityFee + fee.Uint64() + countPriorityFees++ + } + } + avgPriorityFee := float64(totalPriorityFee) / float64(countPriorityFees) + + var totalGasUsedRatio float64 + for _, gasUsedRatio := range feeHistory.GasUsedRatio { + totalGasUsedRatio += gasUsedRatio + } + avgGasUsedRatio := totalGasUsedRatio / float64(len(feeHistory.GasUsedRatio)) + + priorityFeeRatio := avgPriorityFee / avgBaseFee + + congestionScore := (priorityFeeRatio * priorityWeight) + (avgGasUsedRatio * gasUsedWeight) + + return congestionScore +} diff --git a/services/wallet/router/router_helper.go b/services/wallet/router/router_helper.go index 975a1a6e20b..a23a8e3776b 100644 --- a/services/wallet/router/router_helper.go +++ b/services/wallet/router/router_helper.go @@ -192,31 +192,31 @@ func (r *Router) applyCustomFields(ctx context.Context, path *routes.Path, fetch if r.lastInputParams.PathTxCustomParams == nil || len(r.lastInputParams.PathTxCustomParams) == 0 { // if no custom params are provided, use the initial fee mode - maxFeesPerGas, err := fetchedFees.FeeFor(r.lastInputParams.GasFeeMode) + maxFeesPerGas, priorityFee, err := fetchedFees.FeeFor(r.lastInputParams.GasFeeMode) if err != nil { return err } if path.ApprovalRequired { path.ApprovalMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas) path.ApprovalBaseFee = (*hexutil.Big)(fetchedFees.BaseFee) - path.ApprovalPriorityFee = (*hexutil.Big)(fetchedFees.MaxPriorityFeePerGas) + path.ApprovalPriorityFee = (*hexutil.Big)(priorityFee) } path.TxMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas) path.TxBaseFee = (*hexutil.Big)(fetchedFees.BaseFee) - path.TxPriorityFee = (*hexutil.Big)(fetchedFees.MaxPriorityFeePerGas) + path.TxPriorityFee = (*hexutil.Big)(priorityFee) } else { if path.ApprovalRequired { approvalTxIdentityKey := path.TxIdentityKey(true) if approvalTxCustomParams, ok := r.lastInputParams.PathTxCustomParams[approvalTxIdentityKey]; ok { if approvalTxCustomParams.GasFeeMode != fees.GasFeeCustom { - maxFeesPerGas, err := fetchedFees.FeeFor(approvalTxCustomParams.GasFeeMode) + maxFeesPerGas, priorityFee, err := fetchedFees.FeeFor(approvalTxCustomParams.GasFeeMode) if err != nil { return err } path.ApprovalMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas) path.ApprovalBaseFee = (*hexutil.Big)(fetchedFees.BaseFee) - path.ApprovalPriorityFee = (*hexutil.Big)(fetchedFees.MaxPriorityFeePerGas) + path.ApprovalPriorityFee = (*hexutil.Big)(priorityFee) } else { path.ApprovalTxNonce = (*hexutil.Uint64)(&approvalTxCustomParams.Nonce) path.ApprovalGasAmount = approvalTxCustomParams.GasAmount @@ -230,13 +230,13 @@ func (r *Router) applyCustomFields(ctx context.Context, path *routes.Path, fetch txIdentityKey := path.TxIdentityKey(false) if txCustomParams, ok := r.lastInputParams.PathTxCustomParams[txIdentityKey]; ok { if txCustomParams.GasFeeMode != fees.GasFeeCustom { - maxFeesPerGas, err := fetchedFees.FeeFor(txCustomParams.GasFeeMode) + maxFeesPerGas, priorityFee, err := fetchedFees.FeeFor(txCustomParams.GasFeeMode) if err != nil { return err } path.TxMaxFeesPerGas = (*hexutil.Big)(maxFeesPerGas) path.TxBaseFee = (*hexutil.Big)(fetchedFees.BaseFee) - path.TxPriorityFee = (*hexutil.Big)(fetchedFees.MaxPriorityFeePerGas) + path.TxPriorityFee = (*hexutil.Big)(priorityFee) } else { path.TxNonce = (*hexutil.Uint64)(&txCustomParams.Nonce) path.TxGasAmount = txCustomParams.GasAmount diff --git a/tests-functional/utils/wallet_utils.py b/tests-functional/utils/wallet_utils.py index d7eb2d721bb..6a83ce1f85b 100644 --- a/tests-functional/utils/wallet_utils.py +++ b/tests-functional/utils/wallet_utils.py @@ -93,7 +93,7 @@ def check_tx_details(rpc_client, tx_hash, network_id, address_to, expected_amoun assert tx_details["to"].upper() == address_to.upper() -def check_fees(fee_mode, base_fee, max_priority_fee_per_gas, max_fee_per_gas): +def check_fees(fee_mode, base_fee, max_priority_fee_per_gas, max_fee_per_gas, suggested_fee_levels): assert base_fee.startswith("0x") assert max_priority_fee_per_gas.startswith("0x") assert max_fee_per_gas.startswith("0x") @@ -102,12 +102,31 @@ def check_fees(fee_mode, base_fee, max_priority_fee_per_gas, max_fee_per_gas): max_priority_fee_per_gas_int = int(max_priority_fee_per_gas, 16) max_fee_per_gas_int = int(max_fee_per_gas, 16) + low_max_fee_per_gas = int(suggested_fee_levels["low"], 16) + low_priority_max_fee_per_gas = int(suggested_fee_levels["lowPriority"], 16) + medium_max_fee_per_gas = int(suggested_fee_levels["medium"], 16) + medium_priority_max_fee_per_gas = int(suggested_fee_levels["mediumPriority"], 16) + high_max_fee_per_gas = int(suggested_fee_levels["high"], 16) + high_priority_max_fee_per_gas = int(suggested_fee_levels["highPriority"], 16) + if fee_mode == constants.gas_fee_mode_low: + assert max_fee_per_gas_int == low_max_fee_per_gas + assert max_priority_fee_per_gas_int == low_priority_max_fee_per_gas assert base_fee_int + max_priority_fee_per_gas_int == max_fee_per_gas_int elif fee_mode == constants.gas_fee_mode_medium: - assert (2 * base_fee_int + max_priority_fee_per_gas_int) == max_fee_per_gas_int + # calculate variadic fees from high max fees per gas + variadic_fee = high_max_fee_per_gas - high_priority_max_fee_per_gas - 2 * base_fee_int + + assert max_fee_per_gas_int == medium_max_fee_per_gas + assert max_priority_fee_per_gas_int == medium_priority_max_fee_per_gas + assert base_fee_int + variadic_fee + max_priority_fee_per_gas_int == max_fee_per_gas_int elif fee_mode == constants.gas_fee_mode_high: - assert 3 * base_fee_int + max_priority_fee_per_gas_int == max_fee_per_gas_int + # calculate variadic fees from medium max fees per gas + variadic_fee = medium_max_fee_per_gas - medium_priority_max_fee_per_gas - base_fee_int + + assert max_fee_per_gas_int == high_max_fee_per_gas + assert max_priority_fee_per_gas_int == high_priority_max_fee_per_gas + assert 2 * base_fee_int + variadic_fee + max_priority_fee_per_gas_int == max_fee_per_gas_int elif fee_mode == constants.gas_fee_mode_custom: assert base_fee_int + max_priority_fee_per_gas_int == max_fee_per_gas_int else: @@ -120,9 +139,17 @@ def check_fees_for_path(path_name, gas_fee_mode, check_approval, route): continue if check_approval: assert path_tx["ApprovalRequired"] - check_fees(gas_fee_mode, path_tx["ApprovalBaseFee"], path_tx["ApprovalPriorityFee"], path_tx["ApprovalMaxFeesPerGas"]) + check_fees( + gas_fee_mode, + path_tx["ApprovalBaseFee"], + path_tx["ApprovalPriorityFee"], + path_tx["ApprovalMaxFeesPerGas"], + path_tx["SuggestedLevelsForMaxFeesPerGas"], + ) return - check_fees(gas_fee_mode, path_tx["TxBaseFee"], path_tx["TxPriorityFee"], path_tx["TxMaxFeesPerGas"]) + check_fees( + gas_fee_mode, path_tx["TxBaseFee"], path_tx["TxPriorityFee"], path_tx["TxMaxFeesPerGas"], path_tx["SuggestedLevelsForMaxFeesPerGas"] + ) def send_router_transactions_with_signatures(rpc_client, uuid, tx_signatures):