From 4894808839cb2fd0835279342eb5807d482f9c98 Mon Sep 17 00:00:00 2001 From: Sale Djenic Date: Thu, 16 May 2024 09:37:36 +0200 Subject: [PATCH] chore_: review comments applied (part1) --- services/wallet/api.go | 18 +----- services/wallet/bridge/cbridge.go | 4 +- services/wallet/bridge/hop.go | 28 ++++------ services/wallet/fees.go | 23 ++++++-- services/wallet/router_send_type.go | 69 ++++++++++++----------- services/wallet/router_v2.go | 85 +++++++++++++++-------------- 6 files changed, 110 insertions(+), 117 deletions(-) diff --git a/services/wallet/api.go b/services/wallet/api.go index 95e43873a..d0f8e2d00 100644 --- a/services/wallet/api.go +++ b/services/wallet/api.go @@ -445,23 +445,9 @@ func (api *API) GetSuggestedRoutes( disabledToChaindIDs, preferedChainIDs, gasFeeMode, fromLockedAmount) } -func (api *API) GetSuggestedRoutesV2( - ctx context.Context, - sendType SendType, - addrFrom common.Address, - addrTo common.Address, - amountIn *hexutil.Big, - tokenID string, - toTokenID string, - disabledFromChainIDs, - disabledToChaindIDs, - preferedChainIDs []uint64, - gasFeeMode GasFeeMode, - fromLockedAmount map[uint64]*hexutil.Big, -) (*SuggestedRoutesV2, error) { +func (api *API) GetSuggestedRoutesV2(ctx context.Context, input *RouteInputParams) (*SuggestedRoutesV2, error) { log.Debug("call to GetSuggestedRoutesV2") - return api.router.suggestedRoutesV2(ctx, sendType, addrFrom, addrTo, amountIn.ToInt(), tokenID, toTokenID, disabledFromChainIDs, - disabledToChaindIDs, preferedChainIDs, gasFeeMode, fromLockedAmount) + return api.router.suggestedRoutesV2(ctx, input) } // Generates addresses for the provided paths, response doesn't include `HasActivity` value (if you need it check `GetAddressDetails` function) diff --git a/services/wallet/bridge/cbridge.go b/services/wallet/bridge/cbridge.go index f1df7f007..728765dc0 100644 --- a/services/wallet/bridge/cbridge.go +++ b/services/wallet/bridge/cbridge.go @@ -6,7 +6,7 @@ import ( "errors" "fmt" "math/big" - netUrl "net/url" + "net/url" "strconv" "strings" "time" @@ -68,7 +68,7 @@ func (s *CBridge) estimateAmt(from, to *params.Network, amountIn *big.Int, symbo base = testBaseURL } - params := netUrl.Values{} + params := url.Values{} params.Add("src_chain_id", strconv.Itoa(int(from.ChainID))) params.Add("dst_chain_id", strconv.Itoa(int(to.ChainID))) params.Add("token_symbol", symbol) diff --git a/services/wallet/bridge/hop.go b/services/wallet/bridge/hop.go index da54fc70b..cef6ae64d 100644 --- a/services/wallet/bridge/hop.go +++ b/services/wallet/bridge/hop.go @@ -343,24 +343,20 @@ func (h *HopBridge) swapAndSend(chainID uint64, hopArgs *HopTxArgs, signerFn bin } func (h *HopBridge) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) { - const ( - HopMainnetChainName = "ethereum" - HopOptimismChainName = "optimism" - HopArbitrumChainName = "arbitrum" - ) - - fromChainName := HopMainnetChainName - if from.ChainID == walletCommon.OptimismMainnet { - fromChainName = HopOptimismChainName - } else if from.ChainID == walletCommon.ArbitrumMainnet { - fromChainName = HopArbitrumChainName + hopChainsMap := map[uint64]string{ + walletCommon.EthereumMainnet: "ethereum", + walletCommon.OptimismMainnet: "optimism", + walletCommon.ArbitrumMainnet: "arbitrum", } - toChainName := HopMainnetChainName - if from.ChainID == walletCommon.OptimismMainnet { - toChainName = HopOptimismChainName - } else if from.ChainID == walletCommon.ArbitrumMainnet { - toChainName = HopArbitrumChainName + fromChainName, ok := hopChainsMap[from.ChainID] + if !ok { + return nil, nil, errors.New("from chain not supported") + } + + toChainName, ok := hopChainsMap[to.ChainID] + if !ok { + return nil, nil, errors.New("to chain not supported") } params := netUrl.Values{} diff --git a/services/wallet/fees.go b/services/wallet/fees.go index c6b014065..3e051ae45 100644 --- a/services/wallet/fees.go +++ b/services/wallet/fees.go @@ -14,6 +14,7 @@ import ( gaspriceoracle "github.com/status-im/status-go/contracts/gas-price-oracle" "github.com/status-im/status-go/rpc" "github.com/status-im/status-go/rpc/chain" + "github.com/status-im/status-go/services/wallet/common" ) type GasFeeMode int @@ -101,6 +102,9 @@ func gweiToWei(val *big.Float) *big.Int { // ////////////////////////////////////////////////////////////////////////////// // TODO: remove `suggestedFees` function once new router is in place +// +// But we should check the client since this function is exposed to API as `GetSuggestedFees` call. +// Maybe we should keep it and remove it later when the client is ready for that change. // ////////////////////////////////////////////////////////////////////////////// func (f *FeeManager) SuggestedFees(ctx context.Context, chainID uint64) (*SuggestedFees, error) { backend, err := f.RPCClient.EthClient(chainID) @@ -124,14 +128,11 @@ func (f *FeeManager) SuggestedFees(ctx context.Context, chainID uint64) (*Sugges }, nil } - header, err := backend.HeaderByNumber(ctx, nil) + baseFee, err := f.getBaseFee(ctx, backend) if err != nil { return nil, err } - config := params.MainnetChainConfig - baseFee := misc.CalcBaseFee(config, header) - fees, err := f.getFeeHistorySorted(chainID) if err != nil { return &SuggestedFees{ @@ -176,15 +177,25 @@ func (f *FeeManager) SuggestedFees(ctx context.Context, chainID uint64) (*Sugges }, nil } -func (f *FeeManager) getBaseFee(ctx context.Context, client chain.ClientInterface, testnetMode bool) (*big.Int, error) { +func (f *FeeManager) getBaseFee(ctx context.Context, client chain.ClientInterface) (*big.Int, error) { header, err := client.HeaderByNumber(ctx, nil) if err != nil { return nil, err } + chainID := client.NetworkID() + config := params.MainnetChainConfig - if testnetMode { + switch chainID { + case common.EthereumSepolia: + case common.OptimismSepolia: + case common.ArbitrumSepolia: config = params.SepoliaChainConfig + case common.EthereumGoerli: + case common.OptimismGoerli: + case common.ArbitrumGoerli: + config = params.GoerliChainConfig + } baseFee := misc.CalcBaseFee(config, header) diff --git a/services/wallet/router_send_type.go b/services/wallet/router_send_type.go index 5aca6a2e2..78045fa26 100644 --- a/services/wallet/router_send_type.go +++ b/services/wallet/router_send_type.go @@ -88,39 +88,39 @@ func (s SendType) needL1Fee() bool { } func (s SendType) canUseBridge(b bridge.Bridge) bool { - if s == ERC721Transfer && b.Name() != ERC721TransferString { - return false + bridgeName := b.Name() + switch s { + case ERC721Transfer: + return bridgeName == ERC721TransferString + case ERC1155Transfer: + return bridgeName == ERC1155TransferString + default: + return true } - - if s != ERC721Transfer && b.Name() == ERC721TransferString { - return false - } - - if s == ERC1155Transfer && b.Name() != ERC1155TransferString { - return false - } - - if s != ERC1155Transfer && b.Name() == ERC1155TransferString { - return false - } - - return true } func (s SendType) isAvailableFor(network *params.Network) bool { + // Set of network ChainIDs allowed for any type of transaction + allAllowedNetworks := map[uint64]bool{ + walletCommon.EthereumMainnet: true, + walletCommon.EthereumGoerli: true, + walletCommon.EthereumSepolia: true, + } + + // Additional specific networks for the Swap SendType + swapAllowedNetworks := map[uint64]bool{ + walletCommon.EthereumMainnet: true, + walletCommon.OptimismMainnet: true, + walletCommon.ArbitrumMainnet: true, + } + + // Check for Swap specific networks if s == Swap { - return network.ChainID == walletCommon.EthereumMainnet || - network.ChainID == walletCommon.OptimismMainnet || - network.ChainID == walletCommon.ArbitrumMainnet + return swapAllowedNetworks[network.ChainID] } - if s == Transfer || s == Bridge || s.IsCollectiblesTransfer() { - return true - } - - if network.ChainID == walletCommon.EthereumMainnet || - network.ChainID == walletCommon.EthereumGoerli || - network.ChainID == walletCommon.EthereumSepolia { + // Check for any SendType available for all networks + if s == Transfer || s == Bridge || s.IsCollectiblesTransfer() || allAllowedNetworks[network.ChainID] { return true } @@ -132,38 +132,37 @@ func (s SendType) EstimateGas(service *Service, network *params.Network, from co From: (types.Address)(from), Value: (*hexutil.Big)(zero), } - if s == ENSRegister { + switch s { + case ENSRegister: estimate, err := service.ens.API().RegisterEstimate(context.Background(), network.ChainID, tx, EstimateUsername, EstimatePubKey) if err != nil { return 400000 } return estimate - } - if s == ENSRelease { + case ENSRelease: estimate, err := service.ens.API().ReleaseEstimate(context.Background(), network.ChainID, tx, EstimateUsername) if err != nil { return 200000 } return estimate - } - if s == ENSSetPubKey { + case ENSSetPubKey: estimate, err := service.ens.API().SetPubKeyEstimate(context.Background(), network.ChainID, tx, fmt.Sprint(EstimateUsername, ".stateofus.eth"), EstimatePubKey) if err != nil { return 400000 } return estimate - } - if s == StickersBuy { + case StickersBuy: packID := &bigint.BigInt{Int: big.NewInt(2)} estimate, err := service.stickers.API().BuyEstimate(context.Background(), network.ChainID, (types.Address)(from), packID) if err != nil { return 400000 } return estimate - } - return 0 + default: + return 0 + } } diff --git a/services/wallet/router_v2.go b/services/wallet/router_v2.go index a5754406c..bf4dcb6c4 100644 --- a/services/wallet/router_v2.go +++ b/services/wallet/router_v2.go @@ -15,6 +15,20 @@ import ( walletToken "github.com/status-im/status-go/services/wallet/token" ) +type RouteInputParams struct { + SendType SendType `json:"sendType"` + AddrFrom common.Address `json:"addrFrom"` + AddrTo common.Address `json:"addrTo"` + AmountIn *hexutil.Big `json:"amountIn"` + TokenID string `json:"tokenID"` + ToTokenID string `json:"toTokenID"` + DisabledFromChainIDs []uint64 `json:"disabledFromChainIDs"` + DisabledToChaindIDs []uint64 `json:"disabledToChaindIDs"` + PreferedChainIDs []uint64 `json:"preferedChainIDs"` + GasFeeMode GasFeeMode `json:"gasFeeMode"` + FromLockedAmount map[uint64]*hexutil.Big `json:"fromLockedAmount"` +} + type PathV2 struct { BridgeName string From *params.Network // Source chain @@ -325,20 +339,7 @@ func findBestV2(routes [][]*PathV2, tokenPrice float64, nativeChainTokenPrice fl return best } -func (r *Router) suggestedRoutesV2( - ctx context.Context, - sendType SendType, - addrFrom common.Address, - addrTo common.Address, - amountIn *big.Int, - tokenID string, - toTokenID string, - disabledFromChainIDs, - disabledToChaindIDs, - preferedChainIDs []uint64, - gasFeeMode GasFeeMode, - fromLockedAmount map[uint64]*hexutil.Big, -) (*SuggestedRoutesV2, error) { +func (r *Router) suggestedRoutesV2(ctx context.Context, input *RouteInputParams) (*SuggestedRoutesV2, error) { areTestNetworksEnabled, err := r.s.accountsDB.GetTestNetworksEnabled() if err != nil { @@ -362,32 +363,32 @@ func (r *Router) suggestedRoutesV2( continue } - if containsNetworkChainID(network, disabledFromChainIDs) { + if containsNetworkChainID(network, input.DisabledFromChainIDs) { continue } - if !sendType.isAvailableFor(network) { + if !input.SendType.isAvailableFor(network) { continue } - token := sendType.FindToken(r.s, addrFrom, network, tokenID) + token := input.SendType.FindToken(r.s, input.AddrFrom, network, input.TokenID) if token == nil { continue } var toToken *walletToken.Token - if sendType == Swap { - toToken = sendType.FindToken(r.s, common.Address{}, network, toTokenID) + if input.SendType == Swap { + toToken = input.SendType.FindToken(r.s, common.Address{}, network, input.ToTokenID) } amountLocked := false - amountToSend := amountIn - if lockedAmount, ok := fromLockedAmount[network.ChainID]; ok { + amountToSend := input.AmountIn.ToInt() + if lockedAmount, ok := input.FromLockedAmount[network.ChainID]; ok { amountToSend = lockedAmount.ToInt() amountLocked = true } - if len(fromLockedAmount) > 0 { - for chainID, lockedAmount := range fromLockedAmount { + if len(input.FromLockedAmount) > 0 { + for chainID, lockedAmount := range input.FromLockedAmount { if chainID == network.ChainID { continue } @@ -402,7 +403,7 @@ func (r *Router) suggestedRoutesV2( } for _, bridge := range r.bridges { - if !sendType.canUseBridge(bridge) { + if !input.SendType.canUseBridge(bridge) { continue } @@ -411,11 +412,11 @@ func (r *Router) suggestedRoutesV2( continue } - if len(preferedChainIDs) > 0 && !containsNetworkChainID(dest, preferedChainIDs) { + if len(input.PreferedChainIDs) > 0 && !containsNetworkChainID(dest, input.PreferedChainIDs) { continue } - if containsNetworkChainID(dest, disabledToChaindIDs) { + if containsNetworkChainID(dest, input.DisabledToChaindIDs) { continue } @@ -430,25 +431,25 @@ func (r *Router) suggestedRoutesV2( } gasLimit := uint64(0) - if sendType.isTransfer() { - gasLimit, err = bridge.EstimateGas(network, dest, addrFrom, addrTo, token, toToken, amountToSend) + if input.SendType.isTransfer() { + gasLimit, err = bridge.EstimateGas(network, dest, input.AddrFrom, input.AddrTo, token, toToken, amountToSend) if err != nil { continue } } else { - gasLimit = sendType.EstimateGas(r.s, network, addrFrom, tokenID) + gasLimit = input.SendType.EstimateGas(r.s, network, input.AddrFrom, input.TokenID) } approvalContractAddress := bridge.GetContractAddress(network, token) - approvalRequired, approvalAmountRequired, approvalGasLimit, l1ApprovalFee, err := r.requireApproval(ctx, sendType, approvalContractAddress, addrFrom, network, token, amountToSend) + approvalRequired, approvalAmountRequired, approvalGasLimit, l1ApprovalFee, err := r.requireApproval(ctx, input.SendType, approvalContractAddress, input.AddrFrom, network, token, amountToSend) if err != nil { continue } var l1FeeWei uint64 - if sendType.needL1Fee() { + if input.SendType.needL1Fee() { - tx, err := bridge.BuildTx(network, dest, addrFrom, addrTo, token, amountToSend, bonderFees) + tx, err := bridge.BuildTx(network, dest, input.AddrFrom, input.AddrTo, token, amountToSend, bonderFees) if err != nil { continue } @@ -456,7 +457,7 @@ func (r *Router) suggestedRoutesV2( l1FeeWei, _ = r.s.feesManager.GetL1Fee(ctx, network.ChainID, tx) } - baseFee, err := r.s.feesManager.getBaseFee(ctx, client, areTestNetworksEnabled) + baseFee, err := r.s.feesManager.getBaseFee(ctx, client) if err != nil { continue } @@ -466,9 +467,9 @@ func (r *Router) suggestedRoutesV2( continue } selctedPriorityFee := priorityFees.Medium - if gasFeeMode == GasFeeHigh { + if input.GasFeeMode == GasFeeHigh { selctedPriorityFee = priorityFees.High - } else if gasFeeMode == GasFeeLow { + } else if input.GasFeeMode == GasFeeLow { selctedPriorityFee = priorityFees.Low } @@ -523,25 +524,25 @@ func (r *Router) suggestedRoutesV2( group.Wait() - prices, err := sendType.FetchPrices(r.s, tokenID) + prices, err := input.SendType.FetchPrices(r.s, input.TokenID) if err != nil { return nil, err } - suggestedRoutes := newSuggestedRoutesV2(amountIn, candidates, fromLockedAmount, prices[tokenID], prices["ETH"]) + suggestedRoutes := newSuggestedRoutesV2(input.AmountIn.ToInt(), candidates, input.FromLockedAmount, prices[input.TokenID], prices["ETH"]) // check the best route for the required balances for _, path := range suggestedRoutes.Best { if path.requiredTokenBalance != nil && path.requiredTokenBalance.Cmp(big.NewInt(0)) > 0 { tokenBalance := big.NewInt(1) - if sendType == ERC1155Transfer { - tokenBalance, err = r.getERC1155Balance(ctx, path.From, path.FromToken, addrFrom) + if input.SendType == ERC1155Transfer { + tokenBalance, err = r.getERC1155Balance(ctx, path.From, path.FromToken, input.AddrFrom) if err != nil { return nil, err } - } else if sendType != ERC721Transfer { - tokenBalance, err = r.getBalance(ctx, path.From, path.FromToken, addrFrom) + } else if input.SendType != ERC721Transfer { + tokenBalance, err = r.getBalance(ctx, path.From, path.FromToken, input.AddrFrom) if err != nil { return nil, err } @@ -557,7 +558,7 @@ func (r *Router) suggestedRoutesV2( return nil, errors.New("native token not found") } - nativeBalance, err := r.getBalance(ctx, path.From, nativeToken, addrFrom) + nativeBalance, err := r.getBalance(ctx, path.From, nativeToken, input.AddrFrom) if err != nil { return nil, err }