From 3a81b49c5ae0c6613c6befc957715288d1acc814 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Mon, 20 Jan 2025 11:30:27 +0100 Subject: [PATCH] chore(wallet)_: include l1 fees info (for the tx and approval) in the response While ago we've disabled l1 info cause the estimated L1 fees were significantly higher than they should have been (if I remember well, the L1 fees were about 1000 times higher than they should have been). From this point, that wrong value might be coming from unreliable pokt calls/values, these changes bring them back. --- contracts/gas-price-oracle/address.go | 2 + .../wallet/router/pathprocessor/processor.go | 2 +- .../pathprocessor/processor_bridge_celar.go | 7 +- .../pathprocessor/processor_bridge_hop.go | 12 +-- .../pathprocessor/processor_ens_public_key.go | 7 +- .../pathprocessor/processor_ens_register.go | 7 +- .../pathprocessor/processor_ens_release.go | 7 +- .../router/pathprocessor/processor_erc1155.go | 7 +- .../router/pathprocessor/processor_erc721.go | 7 +- .../pathprocessor/processor_stickers_buy.go | 7 +- .../pathprocessor/processor_swap_paraswap.go | 2 +- .../processor_swap_paraswap_test.go | 5 +- .../router/pathprocessor/processor_test.go | 12 ++- .../pathprocessor/processor_transfer.go | 10 +- services/wallet/router/router.go | 22 ++++- services/wallet/router/router_helper.go | 95 +++++++------------ services/wallet/router/router_helper_test.go | 16 ++-- services/wallet/router/routes/router_path.go | 12 +++ .../transfer/transaction_manager_route.go | 29 +----- 19 files changed, 109 insertions(+), 159 deletions(-) diff --git a/contracts/gas-price-oracle/address.go b/contracts/gas-price-oracle/address.go index 7e2e5ff1e1f..ddf05b0918b 100644 --- a/contracts/gas-price-oracle/address.go +++ b/contracts/gas-price-oracle/address.go @@ -13,6 +13,8 @@ var ErrorNotAvailableOnChainID = errors.New("not available for chainID") var contractAddressByChainID = map[uint64]common.Address{ wallet_common.OptimismMainnet: common.HexToAddress("0x8527c030424728cF93E72bDbf7663281A44Eeb22"), wallet_common.OptimismSepolia: common.HexToAddress("0x5230210c2b4995FD5084b0F5FD0D7457aebb5010"), + wallet_common.ArbitrumMainnet: common.HexToAddress("0x8527c030424728cF93E72bDbf7663281A44Eeb22"), + wallet_common.ArbitrumSepolia: common.HexToAddress("0x5230210c2b4995FD5084b0F5FD0D7457aebb5010"), wallet_common.BaseMainnet: common.HexToAddress("0x8527c030424728cF93E72bDbf7663281A44Eeb22"), wallet_common.BaseSepolia: common.HexToAddress("0x5230210c2b4995FD5084b0F5FD0D7457aebb5010"), } diff --git a/services/wallet/router/pathprocessor/processor.go b/services/wallet/router/pathprocessor/processor.go index 084064c1857..27fdbff19b0 100644 --- a/services/wallet/router/pathprocessor/processor.go +++ b/services/wallet/router/pathprocessor/processor.go @@ -26,7 +26,7 @@ type PathProcessor interface { // PackTxInputData packs tx for sending PackTxInputData(params ProcessorInputParams) ([]byte, error) // EstimateGas estimates the gas - EstimateGas(params ProcessorInputParams) (uint64, error) + EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) // CalculateAmountOut calculates the amount out CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) // Send sends the tx, returns the hash and the used nonce (lastUsedNonce is -1 if it's the first tx) diff --git a/services/wallet/router/pathprocessor/processor_bridge_celar.go b/services/wallet/router/pathprocessor/processor_bridge_celar.go index 56258d600c9..81a006afc2c 100644 --- a/services/wallet/router/pathprocessor/processor_bridge_celar.go +++ b/services/wallet/router/pathprocessor/processor_bridge_celar.go @@ -236,7 +236,7 @@ func (c *CelerBridgeProcessor) PackTxInputData(params ProcessorInputParams) ([]b } } -func (s *CelerBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *CelerBridgeProcessor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { @@ -248,11 +248,6 @@ func (s *CelerBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64, value := new(big.Int) - input, err := s.PackTxInputData(params) - if err != nil { - return 0, createBridgeCellerErrorResponse(err) - } - contractAddress, err := s.GetContractAddress(params) if err != nil { return 0, createBridgeCellerErrorResponse(err) diff --git a/services/wallet/router/pathprocessor/processor_bridge_hop.go b/services/wallet/router/pathprocessor/processor_bridge_hop.go index e1eb1b6aff5..ed6f69bdea9 100644 --- a/services/wallet/router/pathprocessor/processor_bridge_hop.go +++ b/services/wallet/router/pathprocessor/processor_bridge_hop.go @@ -195,6 +195,9 @@ func (c *HopBridgeProcessor) getAppropriateABI(contractType string, chainID uint } func (h *HopBridgeProcessor) PackTxInputData(params ProcessorInputParams) ([]byte, error) { + if params.TestsMode { + return []byte{}, nil + } _, contractType, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol) if err != nil { return []byte{}, createBridgeHopErrorResponse(err) @@ -232,7 +235,7 @@ func (h *HopBridgeProcessor) packTxInputDataInternally(params ProcessorInputPara return []byte{}, ErrContractTypeNotSupported } -func (h *HopBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (h *HopBridgeProcessor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[h.Name()]; ok { @@ -247,12 +250,7 @@ func (h *HopBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64, e value = params.AmountIn } - contractAddress, contractType, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol) - if err != nil { - return 0, createBridgeHopErrorResponse(err) - } - - input, err := h.packTxInputDataInternally(params, contractType) + contractAddress, _, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol) if err != nil { return 0, createBridgeHopErrorResponse(err) } diff --git a/services/wallet/router/pathprocessor/processor_ens_public_key.go b/services/wallet/router/pathprocessor/processor_ens_public_key.go index d49fea77f5a..b223ad61622 100644 --- a/services/wallet/router/pathprocessor/processor_ens_public_key.go +++ b/services/wallet/router/pathprocessor/processor_ens_public_key.go @@ -63,7 +63,7 @@ func (s *ENSPublicKeyProcessor) PackTxInputData(params ProcessorInputParams) ([] return resolverABI.Pack("setPubkey", walletCommon.NameHash(params.Username), x, y) } -func (s *ENSPublicKeyProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *ENSPublicKeyProcessor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { @@ -78,11 +78,6 @@ func (s *ENSPublicKeyProcessor) EstimateGas(params ProcessorInputParams) (uint64 return 0, createENSPublicKeyErrorResponse(err) } - input, err := s.PackTxInputData(params) - if err != nil { - return 0, createENSPublicKeyErrorResponse(err) - } - ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID) if err != nil { return 0, err diff --git a/services/wallet/router/pathprocessor/processor_ens_register.go b/services/wallet/router/pathprocessor/processor_ens_register.go index 8dfbaad9011..cb4574bf60a 100644 --- a/services/wallet/router/pathprocessor/processor_ens_register.go +++ b/services/wallet/router/pathprocessor/processor_ens_register.go @@ -99,7 +99,7 @@ func (s *ENSRegisterProcessor) PackTxInputData(params ProcessorInputParams) ([]b return sntABI.Pack("approveAndCall", registryAddr, price, extraData) } -func (s *ENSRegisterProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *ENSRegisterProcessor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { @@ -114,11 +114,6 @@ func (s *ENSRegisterProcessor) EstimateGas(params ProcessorInputParams) (uint64, return 0, createENSRegisterProcessorErrorResponse(err) } - input, err := s.PackTxInputData(params) - if err != nil { - return 0, createENSRegisterProcessorErrorResponse(err) - } - ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID) if err != nil { return 0, createENSRegisterProcessorErrorResponse(err) diff --git a/services/wallet/router/pathprocessor/processor_ens_release.go b/services/wallet/router/pathprocessor/processor_ens_release.go index 7d0dbdfee4f..bdcac73661c 100644 --- a/services/wallet/router/pathprocessor/processor_ens_release.go +++ b/services/wallet/router/pathprocessor/processor_ens_release.go @@ -63,7 +63,7 @@ func (s *ENSReleaseProcessor) PackTxInputData(params ProcessorInputParams) ([]by return registrarABI.Pack("release", walletCommon.UsernameToLabel(name)) } -func (s *ENSReleaseProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *ENSReleaseProcessor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { @@ -78,11 +78,6 @@ func (s *ENSReleaseProcessor) EstimateGas(params ProcessorInputParams) (uint64, return 0, createENSReleaseErrorResponse(err) } - input, err := s.PackTxInputData(params) - if err != nil { - return 0, createENSReleaseErrorResponse(err) - } - ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID) if err != nil { return 0, createENSReleaseErrorResponse(err) diff --git a/services/wallet/router/pathprocessor/processor_erc1155.go b/services/wallet/router/pathprocessor/processor_erc1155.go index 36e6784e938..c731a3f8261 100644 --- a/services/wallet/router/pathprocessor/processor_erc1155.go +++ b/services/wallet/router/pathprocessor/processor_erc1155.go @@ -74,7 +74,7 @@ func (s *ERC1155Processor) PackTxInputData(params ProcessorInputParams) ([]byte, ) } -func (s *ERC1155Processor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *ERC1155Processor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { @@ -91,11 +91,6 @@ func (s *ERC1155Processor) EstimateGas(params ProcessorInputParams) (uint64, err value := new(big.Int) - input, err := s.PackTxInputData(params) - if err != nil { - return 0, createERC1155ErrorResponse(err) - } - msg := ethereum.CallMsg{ From: params.FromAddr, To: ¶ms.FromToken.Address, diff --git a/services/wallet/router/pathprocessor/processor_erc721.go b/services/wallet/router/pathprocessor/processor_erc721.go index 67f9f7d0dc4..43a72867bef 100644 --- a/services/wallet/router/pathprocessor/processor_erc721.go +++ b/services/wallet/router/pathprocessor/processor_erc721.go @@ -111,7 +111,7 @@ func (s *ERC721Processor) PackTxInputData(params ProcessorInputParams) ([]byte, return s.packTxInputDataInternally(params, functionNameTransferFrom) } -func (s *ERC721Processor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *ERC721Processor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { @@ -128,11 +128,6 @@ func (s *ERC721Processor) EstimateGas(params ProcessorInputParams) (uint64, erro value := new(big.Int) - input, err := s.PackTxInputData(params) - if err != nil { - return 0, createERC721ErrorResponse(err) - } - msg := ethereum.CallMsg{ From: params.FromAddr, To: ¶ms.FromToken.Address, diff --git a/services/wallet/router/pathprocessor/processor_stickers_buy.go b/services/wallet/router/pathprocessor/processor_stickers_buy.go index ddd1d8a0fbf..25b566b9bca 100644 --- a/services/wallet/router/pathprocessor/processor_stickers_buy.go +++ b/services/wallet/router/pathprocessor/processor_stickers_buy.go @@ -88,7 +88,7 @@ func (s *StickersBuyProcessor) PackTxInputData(params ProcessorInputParams) ([]b return sntABI.Pack("approveAndCall", stickerMarketAddress, packInfo.Price, extraData) } -func (s *StickersBuyProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *StickersBuyProcessor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { @@ -103,11 +103,6 @@ func (s *StickersBuyProcessor) EstimateGas(params ProcessorInputParams) (uint64, return 0, createStickersBuyErrorResponse(err) } - input, err := s.PackTxInputData(params) - if err != nil { - return 0, createStickersBuyErrorResponse(err) - } - ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID) if err != nil { return 0, createStickersBuyErrorResponse(err) diff --git a/services/wallet/router/pathprocessor/processor_swap_paraswap.go b/services/wallet/router/pathprocessor/processor_swap_paraswap.go index 2e6abb4aa4a..56d0dc42158 100644 --- a/services/wallet/router/pathprocessor/processor_swap_paraswap.go +++ b/services/wallet/router/pathprocessor/processor_swap_paraswap.go @@ -173,7 +173,7 @@ func (s *SwapParaswapProcessor) PackTxInputData(params ProcessorInputParams) ([] return []byte{}, nil } -func (s *SwapParaswapProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *SwapParaswapProcessor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { diff --git a/services/wallet/router/pathprocessor/processor_swap_paraswap_test.go b/services/wallet/router/pathprocessor/processor_swap_paraswap_test.go index 63d088d3f49..69ffc549be3 100644 --- a/services/wallet/router/pathprocessor/processor_swap_paraswap_test.go +++ b/services/wallet/router/pathprocessor/processor_swap_paraswap_test.go @@ -17,6 +17,7 @@ import ( mock_paraswap "github.com/status-im/status-go/services/wallet/thirdparty/paraswap/mock" "github.com/status-im/status-go/services/wallet/token" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -136,7 +137,9 @@ func TestParaswapErrors(t *testing.T) { for _, tc := range testCases { expectClientFetchPriceRoute(client, paraswap.Route{}, errors.New(tc.clientError)) - _, err := processor.EstimateGas(testInputParams) + inputData, err := processor.PackTxInputData(testInputParams) + assert.NoError(t, err) + _, err = processor.EstimateGas(testInputParams, inputData) require.Equal(t, tc.processorError.Error(), err.Error()) } } diff --git a/services/wallet/router/pathprocessor/processor_test.go b/services/wallet/router/pathprocessor/processor_test.go index 049da12105c..d6f6ca8835b 100644 --- a/services/wallet/router/pathprocessor/processor_test.go +++ b/services/wallet/router/pathprocessor/processor_test.go @@ -322,7 +322,9 @@ func TestPathProcessors(t *testing.T) { assert.Equal(t, expResult.expected, result) if tt.input.TestEstimationMap != nil { - estimatedGas, err := processor.EstimateGas(tt.input) + inputData, err := processor.PackTxInputData(tt.input) + assert.NoError(t, err) + estimatedGas, err := processor.EstimateGas(tt.input, inputData) assert.NoError(t, err) assert.Greater(t, estimatedGas, uint64(0)) @@ -330,12 +332,16 @@ func TestPathProcessors(t *testing.T) { input.TestEstimationMap = map[string]requests.Estimation{ "randomName": {Value: 10000}, } - estimatedGas, err = processor.EstimateGas(input) + inputData, err = processor.PackTxInputData(tt.input) + assert.NoError(t, err) + estimatedGas, err = processor.EstimateGas(input, inputData) assert.Error(t, err) assert.Equal(t, ErrNoEstimationFound, err) assert.Equal(t, uint64(0), estimatedGas) } else { - estimatedGas, err := processor.EstimateGas(tt.input) + inputData, err := processor.PackTxInputData(tt.input) + assert.NoError(t, err) + estimatedGas, err := processor.EstimateGas(tt.input, inputData) assert.Error(t, err) assert.Equal(t, ErrNoEstimationFound, err) assert.Equal(t, uint64(0), estimatedGas) diff --git a/services/wallet/router/pathprocessor/processor_transfer.go b/services/wallet/router/pathprocessor/processor_transfer.go index 0f1f13de3cf..6fd8bbe1cb0 100644 --- a/services/wallet/router/pathprocessor/processor_transfer.go +++ b/services/wallet/router/pathprocessor/processor_transfer.go @@ -54,6 +54,9 @@ func (s *TransferProcessor) CalculateFees(params ProcessorInputParams) (*big.Int } func (s *TransferProcessor) PackTxInputData(params ProcessorInputParams) ([]byte, error) { + if params.TestsMode { + return []byte{}, nil + } if params.FromToken.IsNative() { return []byte{}, nil } else { @@ -68,7 +71,7 @@ func (s *TransferProcessor) PackTxInputData(params ProcessorInputParams) ([]byte } } -func (s *TransferProcessor) EstimateGas(params ProcessorInputParams) (uint64, error) { +func (s *TransferProcessor) EstimateGas(params ProcessorInputParams, input []byte) (uint64, error) { if params.TestsMode { if params.TestEstimationMap != nil { if val, ok := params.TestEstimationMap[s.Name()]; ok { @@ -81,11 +84,6 @@ func (s *TransferProcessor) EstimateGas(params ProcessorInputParams) (uint64, er estimation := uint64(0) var err error - input, err := s.PackTxInputData(params) - if err != nil { - return 0, createTransferErrorResponse(err) - } - if params.FromToken.IsNative() { estimation, err = s.transactor.EstimateGas(params.FromChain, params.FromAddr, params.ToAddr, params.AmountIn, input) if err != nil { diff --git a/services/wallet/router/router.go b/services/wallet/router/router.go index 843f0a6f5af..c7098ada3d7 100644 --- a/services/wallet/router/router.go +++ b/services/wallet/router/router.go @@ -786,7 +786,13 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp continue } - gasLimit, err := pProcessor.EstimateGas(processorInputParams) + txPackedData, err := pProcessor.PackTxInputData(processorInputParams) + if err != nil { + appendProcessorErrorFn(pProcessor.Name(), input.SendType, processorInputParams.FromChain.ChainID, processorInputParams.ToChain.ChainID, processorInputParams.AmountIn, err) + continue + } + + gasLimit, err := pProcessor.EstimateGas(processorInputParams, txPackedData) if err != nil { appendProcessorErrorFn(pProcessor.Name(), input.SendType, processorInputParams.FromChain.ChainID, processorInputParams.ToChain.ChainID, processorInputParams.AmountIn, err) continue @@ -803,12 +809,20 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp continue } - var approvalGasLimit uint64 + var ( + approvalGasLimit uint64 + approvalPackedData []byte + ) if approvalRequired { if processorInputParams.TestsMode { approvalGasLimit = processorInputParams.TestApprovalGasEstimation } else { - approvalGasLimit, err = r.estimateGasForApproval(processorInputParams, &approvalContractAddress) + approvalPackedData, err := walletCommon.PackApprovalInputData(processorInputParams.AmountIn, &approvalContractAddress) + if err != nil { + appendProcessorErrorFn(pProcessor.Name(), input.SendType, processorInputParams.FromChain.ChainID, processorInputParams.ToChain.ChainID, processorInputParams.AmountIn, err) + continue + } + approvalGasLimit, err = r.estimateGasForApproval(processorInputParams, approvalPackedData) if err != nil { appendProcessorErrorFn(pProcessor.Name(), input.SendType, processorInputParams.FromChain.ChainID, processorInputParams.ToChain.ChainID, processorInputParams.AmountIn, err) continue @@ -834,6 +848,7 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp AmountOut: (*hexutil.Big)(amountOut), // set params that we don't want to be recalculated with every new block creation + TxPackedData: txPackedData, TxGasAmount: gasLimit, TxBonderFees: (*hexutil.Big)(bonderFees), TxTokenFees: (*hexutil.Big)(tokenFees), @@ -841,6 +856,7 @@ func (r *Router) resolveCandidates(ctx context.Context, input *requests.RouteInp ApprovalRequired: approvalRequired, ApprovalAmountRequired: (*hexutil.Big)(approvalAmountRequired), ApprovalContractAddress: &approvalContractAddress, + ApprovalPackedData: approvalPackedData, ApprovalGasAmount: approvalGasLimit, SubtractFees: amountOption.subtractFees, diff --git a/services/wallet/router/router_helper.go b/services/wallet/router/router_helper.go index bc168922ccf..4d08a88c59c 100644 --- a/services/wallet/router/router_helper.go +++ b/services/wallet/router/router_helper.go @@ -70,12 +70,7 @@ func (r *Router) requireApproval(ctx context.Context, sendType sendtype.SendType return true, params.AmountIn, nil } -func (r *Router) estimateGasForApproval(params pathprocessor.ProcessorInputParams, approvalContractAddress *common.Address) (uint64, error) { - data, err := walletCommon.PackApprovalInputData(params.AmountIn, approvalContractAddress) - if err != nil { - return 0, err - } - +func (r *Router) estimateGasForApproval(params pathprocessor.ProcessorInputParams, input []byte) (uint64, error) { ethClient, err := r.rpcClient.EthClient(params.FromChain.ChainID) if err != nil { return 0, err @@ -85,43 +80,33 @@ func (r *Router) estimateGasForApproval(params pathprocessor.ProcessorInputParam From: params.FromAddr, To: ¶ms.FromToken.Address, Value: walletCommon.ZeroBigIntValue(), - Data: data, + Data: input, }) } -func (r *Router) calculateApprovalL1Fee(amountIn *big.Int, chainID uint64, approvalContractAddress *common.Address) (uint64, error) { +func (r *Router) calculateL1Fee(chainID uint64, data []byte) (*big.Int, error) { ethClient, err := r.rpcClient.EthClient(chainID) if err != nil { - return 0, err + return nil, err } - return CalculateApprovalL1Fee(amountIn, chainID, approvalContractAddress, ethClient) + return CalculateL1Fee(chainID, data, ethClient) } -func CalculateApprovalL1Fee(amountIn *big.Int, chainID uint64, approvalContractAddress *common.Address, ethClient chain.ClientInterface) (uint64, error) { - data, err := walletCommon.PackApprovalInputData(amountIn, approvalContractAddress) +func CalculateL1Fee(chainID uint64, data []byte, ethClient chain.ClientInterface) (*big.Int, error) { + oracleContractAddress, err := gaspriceoracle.ContractAddress(chainID) if err != nil { - return 0, err + return nil, err } - var l1Fee uint64 - oracleContractAddress, err := gaspriceoracle.ContractAddress(chainID) - if err == nil { - oracleContract, err := gaspriceoracle.NewGaspriceoracleCaller(oracleContractAddress, ethClient) - if err != nil { - return 0, err - } - - callOpt := &bind.CallOpts{} - - l1FeeResult, err := oracleContract.GetL1Fee(callOpt, data) - if err == nil { - l1Fee = l1FeeResult.Uint64() - } + oracleContract, err := gaspriceoracle.NewGaspriceoracleCaller(oracleContractAddress, ethClient) + if err != nil { + return nil, err } - // return 0 if we failed to get the fee - return l1Fee, nil + callOpt := &bind.CallOpts{} + + return oracleContract.GetL1Fee(callOpt, data) } func (r *Router) getERC1155Balance(ctx context.Context, network *params.Network, token *token.Token, account common.Address) (*big.Int, error) { @@ -268,17 +253,21 @@ func (r *Router) applyCustomFields(ctx context.Context, path *routes.Path, fetch func (r *Router) evaluateAndUpdatePathDetails(ctx context.Context, path *routes.Path, fetchedFees *fees.SuggestedFees, usedNonces map[uint64]uint64, testsMode bool, testApprovalL1Fee uint64) (err error) { - var ( - l1ApprovalFee uint64 - ) + l1TxFeeWei := big.NewInt(0) + l1ApprovalFeeWei := big.NewInt(0) + + needL1Fee := path.FromChain.ChainID != walletCommon.EthereumMainnet && + path.FromChain.ChainID != walletCommon.EthereumSepolia + if testsMode { usedNonces[path.FromChain.ChainID] = usedNonces[path.FromChain.ChainID] + 1 } - if path.ApprovalRequired { + + if path.ApprovalRequired && needL1Fee { if testsMode { - l1ApprovalFee = testApprovalL1Fee + l1ApprovalFeeWei = big.NewInt(int64(testApprovalL1Fee)) } else { - l1ApprovalFee, err = r.calculateApprovalL1Fee(path.AmountIn.ToInt(), path.FromChain.ChainID, path.ApprovalContractAddress) + l1ApprovalFeeWei, err = r.calculateL1Fee(path.FromChain.ChainID, path.ApprovalPackedData) if err != nil { return err } @@ -290,38 +279,26 @@ func (r *Router) evaluateAndUpdatePathDetails(ctx context.Context, path *routes. return } - // TODO: keep l1 fees at 0 until we have the correct algorithm, as we do base fee x 2 that should cover the l1 fees - var l1FeeWei uint64 = 0 - // if input.SendType.needL1Fee() { - // txInputData, err := pProcessor.PackTxInputData(processorInputParams) - // if err != nil { - // continue - // } - - // l1FeeWei, _ = r.feesManager.GetL1Fee(ctx, network.ChainID, txInputData) - // } + if needL1Fee { + if !testsMode { + l1TxFeeWei, err = r.calculateL1Fee(path.FromChain.ChainID, path.TxPackedData) + if err != nil { + return err + } + } + } // calculate ETH fees ethTotalFees := big.NewInt(0) txFeeInWei := new(big.Int).Mul(path.TxMaxFeesPerGas.ToInt(), big.NewInt(int64(path.TxGasAmount))) ethTotalFees.Add(ethTotalFees, txFeeInWei) - - txL1FeeInWei := big.NewInt(0) - if l1FeeWei > 0 { - txL1FeeInWei = big.NewInt(int64(l1FeeWei)) - ethTotalFees.Add(ethTotalFees, txL1FeeInWei) - } + ethTotalFees.Add(ethTotalFees, l1TxFeeWei) approvalFeeInWei := big.NewInt(0) - approvalL1FeeInWei := big.NewInt(0) if path.ApprovalRequired { approvalFeeInWei.Mul(path.ApprovalMaxFeesPerGas.ToInt(), big.NewInt(int64(path.ApprovalGasAmount))) ethTotalFees.Add(ethTotalFees, approvalFeeInWei) - - if l1ApprovalFee > 0 { - approvalL1FeeInWei = big.NewInt(int64(l1ApprovalFee)) - ethTotalFees.Add(ethTotalFees, approvalL1FeeInWei) - } + ethTotalFees.Add(ethTotalFees, l1ApprovalFeeWei) } // calculate required balances (bonder and token fees are already included in the amountIn by Hop bridge (once we include Celar we need to check how they handle the fees)) @@ -342,10 +319,10 @@ func (r *Router) evaluateAndUpdatePathDetails(ctx context.Context, path *routes. path.SuggestedLevelsForMaxFeesPerGas = fetchedFees.MaxFeesLevels path.TxFee = (*hexutil.Big)(txFeeInWei) - path.TxL1Fee = (*hexutil.Big)(txL1FeeInWei) + path.TxL1Fee = (*hexutil.Big)(l1TxFeeWei) path.ApprovalFee = (*hexutil.Big)(approvalFeeInWei) - path.ApprovalL1Fee = (*hexutil.Big)(approvalL1FeeInWei) + path.ApprovalL1Fee = (*hexutil.Big)(l1ApprovalFeeWei) path.TxTotalFee = (*hexutil.Big)(ethTotalFees) diff --git a/services/wallet/router/router_helper_test.go b/services/wallet/router/router_helper_test.go index b5c3567261a..8622e4dad83 100644 --- a/services/wallet/router/router_helper_test.go +++ b/services/wallet/router/router_helper_test.go @@ -37,8 +37,7 @@ func (s *CalculateFeesTestSuite) TearDownTest() { func (s *CalculateFeesTestSuite) TestCalculateApprovalL1Fee_Success() { // Test inputs - amountIn := big.NewInt(1000) - approvalContractAddress := common.HexToAddress("0xApprovalAddress") + approvalTxInputData := []byte("0x123456") expectedFee := big.NewInt(500) // Prepare mock return data @@ -56,17 +55,16 @@ func (s *CalculateFeesTestSuite) TestCalculateApprovalL1Fee_Success() { }) // Call the function - fee, err := router.CalculateApprovalL1Fee(amountIn, s.chainID, &approvalContractAddress, s.ethClient) + fee, err := router.CalculateL1Fee(s.chainID, approvalTxInputData, s.ethClient) // Assertions require.NoError(s.T(), err) - require.Equal(s.T(), expectedFee.Uint64(), fee) + require.Equal(s.T(), expectedFee, fee) } func (s *CalculateFeesTestSuite) TestCalculateApprovalL1Fee_ZeroFeeOnContractCallError() { // Test inputs - amountIn := big.NewInt(1000) - approvalContractAddress := common.HexToAddress("0xApprovalAddress") + approvalTxInputData := []byte("0x123456") // Mock CallContract to return an error s.ethClient.EXPECT(). @@ -74,11 +72,11 @@ func (s *CalculateFeesTestSuite) TestCalculateApprovalL1Fee_ZeroFeeOnContractCal Return(nil, errors.New("contract call failed")) // Call the function - fee, err := router.CalculateApprovalL1Fee(amountIn, s.chainID, &approvalContractAddress, s.ethClient) + fee, err := router.CalculateL1Fee(s.chainID, approvalTxInputData, s.ethClient) // Assertions - require.Nil(s.T(), err) - require.Equal(s.T(), uint64(0), fee) + require.NotNil(s.T(), err) + require.Nil(s.T(), fee) } func TestCalculateFeesTestSuite(t *testing.T) { diff --git a/services/wallet/router/routes/router_path.go b/services/wallet/router/routes/router_path.go index 2ac001ee21e..493524ae550 100644 --- a/services/wallet/router/routes/router_path.go +++ b/services/wallet/router/routes/router_path.go @@ -27,6 +27,7 @@ type Path struct { SuggestedMaxPriorityFee *hexutil.Big // Suggested max priority fee by the network (in ETH WEI) CurrentBaseFee *hexutil.Big // Current network base fee (in ETH WEI) + TxPackedData []byte // Packed data for the transaction TxNonce *hexutil.Uint64 // Nonce for the transaction TxMaxFeesPerGas *hexutil.Big // Max fees per gas (determined by client via GasFeeMode, in ETH WEI) TxBaseFee *hexutil.Big // Base fee for the transaction (in ETH WEI) @@ -42,6 +43,7 @@ type Path struct { ApprovalRequired bool // Is approval required for the transaction ApprovalAmountRequired *hexutil.Big // Amount required for the approval transaction ApprovalContractAddress *common.Address // Address of the contract that needs to be approved + ApprovalPackedData []byte // Packed data for the approval transaction ApprovalTxNonce *hexutil.Uint64 // Nonce for the transaction ApprovalMaxFeesPerGas *hexutil.Big // Max fees per gas (determined by client via GasFeeMode, in ETH WEI) ApprovalBaseFee *hexutil.Big // Base fee for the approval transaction (in ETH WEI) @@ -132,6 +134,11 @@ func (p *Path) Copy() *Path { newPath.CurrentBaseFee = (*hexutil.Big)(big.NewInt(0).Set(p.CurrentBaseFee.ToInt())) } + if p.TxPackedData != nil { + newPath.TxPackedData = make([]byte, len(p.TxPackedData)) + copy(newPath.TxPackedData, p.TxPackedData) + } + if p.TxNonce != nil { txNonce := *p.TxNonce newPath.TxNonce = &txNonce @@ -174,6 +181,11 @@ func (p *Path) Copy() *Path { newPath.ApprovalContractAddress = &addr } + if p.ApprovalPackedData != nil { + newPath.ApprovalPackedData = make([]byte, len(p.ApprovalPackedData)) + copy(newPath.ApprovalPackedData, p.ApprovalPackedData) + } + if p.ApprovalTxNonce != nil { approvalTxNonce := *p.ApprovalTxNonce newPath.ApprovalTxNonce = &approvalTxNonce diff --git a/services/wallet/transfer/transaction_manager_route.go b/services/wallet/transfer/transaction_manager_route.go index 190aaa65bf4..21a387c37ae 100644 --- a/services/wallet/transfer/transaction_manager_route.go +++ b/services/wallet/transfer/transaction_manager_route.go @@ -85,11 +85,6 @@ func buildApprovalTxForPath(transactor transactions.TransactorIface, path *route lastUsedNonce = nonce } - data, err := walletCommon.PackApprovalInputData(path.AmountIn.ToInt(), path.ApprovalContractAddress) - if err != nil { - return nil, err - } - addrTo := types.Address(path.FromToken.Address) approavalSendArgs := &wallettypes.SendTxArgs{ Version: wallettypes.SendTxArgsVersion1, @@ -98,7 +93,7 @@ func buildApprovalTxForPath(transactor transactions.TransactorIface, path *route From: types.Address(addressFrom), To: &addrTo, Value: (*hexutil.Big)(big.NewInt(0)), - Data: data, + Data: path.ApprovalPackedData, Nonce: path.ApprovalTxNonce, Gas: (*hexutil.Uint64)(&path.ApprovalGasAmount), MaxFeePerGas: path.ApprovalMaxFeesPerGas, @@ -133,26 +128,6 @@ func buildTxForPath(path *routes.Path, pathProcessors map[string]pathprocessor.P lastUsedNonce = nonce } - processorInputParams := pathprocessor.ProcessorInputParams{ - FromAddr: params.AddressFrom, - ToAddr: params.AddressTo, - FromChain: path.FromChain, - ToChain: path.ToChain, - FromToken: path.FromToken, - ToToken: path.ToToken, - AmountIn: path.AmountIn.ToInt(), - AmountOut: path.AmountOut.ToInt(), - - Username: params.Username, - PublicKey: params.PublicKey, - PackID: params.PackID, - } - - data, err := pathProcessors[path.ProcessorName].PackTxInputData(processorInputParams) - if err != nil { - return nil, err - } - addrTo := types.Address(params.AddressTo) sendArgs := &wallettypes.SendTxArgs{ Version: wallettypes.SendTxArgsVersion1, @@ -161,7 +136,7 @@ func buildTxForPath(path *routes.Path, pathProcessors map[string]pathprocessor.P From: types.Address(params.AddressFrom), To: &addrTo, Value: path.AmountIn, - Data: data, + Data: path.TxPackedData, Nonce: path.TxNonce, Gas: (*hexutil.Uint64)(&path.TxGasAmount), MaxFeePerGas: path.TxMaxFeesPerGas,