fix_: hop bridge improvements

- handling `null` values in the Hop response
- using data returned from the Hop api when preparing data for estimation and calling `swapAndSend` and `sendToL2`
- estimating gas for bridges implemented in the bridges implementation types, avoiding wrong gas for placing bridge transactions
This commit is contained in:
Sale Djenic 2024-05-21 16:33:36 +02:00 committed by saledjenic
parent 4e51b5ba24
commit c74931c333
12 changed files with 195 additions and 143 deletions

View File

@ -393,7 +393,12 @@ func (s *Service) estimateL1Fee(ctx context.Context, chainID uint64, sendArgs tr
return 0, err return 0, err
} }
return s.feeManager.GetL1Fee(ctx, chainID, transaction) data, err := transaction.MarshalBinary()
if err != nil {
return 0, err
}
return s.feeManager.GetL1Fee(ctx, chainID, data)
} }
func (s *Service) estimateMethodForTokenInstance(ctx context.Context, contractInstance TokenInstance, chainID uint64, contractAddress string, fromAddress string, methodName string, args ...interface{}) (uint64, error) { func (s *Service) estimateMethodForTokenInstance(ctx context.Context, contractInstance TokenInstance, chainID uint64, contractAddress string, fromAddress string, methodName string, args ...interface{}) (uint64, error) {

View File

@ -107,6 +107,8 @@ type Bridge interface {
AvailableFor(from *params.Network, to *params.Network, token *token.Token, toToken *token.Token) (bool, error) AvailableFor(from *params.Network, to *params.Network, token *token.Token, toToken *token.Token) (bool, error)
// calculates the fees for the bridge and returns the amount BonderFee and TokenFee (used for bridges) // calculates the fees for the bridge and returns the amount BonderFee and TokenFee (used for bridges)
CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error)
// Pack the method for sending tx and method call's data
PackTxInputData(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error)
EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error)
CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error)
Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (types.Hash, error) Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (types.Hash, error)

View File

@ -196,28 +196,22 @@ func (s *CBridge) CalculateFees(from, to *params.Network, token *token.Token, am
return big.NewInt(0), new(big.Int).Add(baseFee, percFee), nil return big.NewInt(0), new(big.Int).Add(baseFee, percFee), nil
} }
func (s *CBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) { func (c *CBridge) PackTxInputData(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
var input []byte
value := new(big.Int)
abi, err := abi.JSON(strings.NewReader(celer.CelerABI)) abi, err := abi.JSON(strings.NewReader(celer.CelerABI))
if err != nil { if err != nil {
return 0, err return []byte{}, err
} }
if token.IsNative() { if token.IsNative() {
input, err = abi.Pack("sendNative", return abi.Pack("sendNative",
to, to,
amountIn, amountIn,
toNetwork.ChainID, toNetwork.ChainID,
uint64(time.Now().UnixMilli()), uint64(time.Now().UnixMilli()),
500, 500,
) )
if err != nil {
return 0, err
}
} else { } else {
input, err = abi.Pack("send", return abi.Pack("send",
to, to,
token.Address, token.Address,
amountIn, amountIn,
@ -225,9 +219,15 @@ func (s *CBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Net
uint64(time.Now().UnixMilli()), uint64(time.Now().UnixMilli()),
500, 500,
) )
if err != nil { }
return 0, err }
}
func (s *CBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) {
value := new(big.Int)
input, err := s.PackTxInputData(fromNetwork, toNetwork, from, to, token, amountIn)
if err != nil {
return 0, err
} }
contractAddress := s.GetContractAddress(fromNetwork, nil) contractAddress := s.GetContractAddress(fromNetwork, nil)

View File

@ -49,31 +49,35 @@ func (s *ERC1155TransferBridge) CalculateFees(from, to *params.Network, token *t
return big.NewInt(0), big.NewInt(0), nil return big.NewInt(0), big.NewInt(0), nil
} }
func (s *ERC1155TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) { func (s *ERC1155TransferBridge) PackTxInputData(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
ethClient, err := s.rpcClient.EthClient(fromNetwork.ChainID)
if err != nil {
return 0, err
}
var input []byte
value := new(big.Int)
abi, err := abi.JSON(strings.NewReader(ierc1155.Ierc1155ABI)) abi, err := abi.JSON(strings.NewReader(ierc1155.Ierc1155ABI))
if err != nil { if err != nil {
return 0, err return []byte{}, err
} }
id, success := big.NewInt(0).SetString(token.Symbol, 0) id, success := big.NewInt(0).SetString(token.Symbol, 0)
if !success { if !success {
return 0, fmt.Errorf("failed to convert %s to big.Int", token.Symbol) return []byte{}, fmt.Errorf("failed to convert %s to big.Int", token.Symbol)
} }
input, err = abi.Pack("safeTransferFrom",
return abi.Pack("safeTransferFrom",
from, from,
to, to,
id, id,
amountIn, amountIn,
[]byte{}, []byte{},
) )
}
func (s *ERC1155TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) {
ethClient, err := s.rpcClient.EthClient(fromNetwork.ChainID)
if err != nil {
return 0, err
}
value := new(big.Int)
input, err := s.PackTxInputData(fromNetwork, toNetwork, from, to, token, amountIn)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -48,29 +48,33 @@ func (s *ERC721TransferBridge) CalculateFees(from, to *params.Network, token *to
return big.NewInt(0), big.NewInt(0), nil return big.NewInt(0), big.NewInt(0), nil
} }
func (s *ERC721TransferBridge) PackTxInputData(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
abi, err := abi.JSON(strings.NewReader(collectibles.CollectiblesMetaData.ABI))
if err != nil {
return []byte{}, err
}
id, success := big.NewInt(0).SetString(token.Symbol, 0)
if !success {
return []byte{}, fmt.Errorf("failed to convert %s to big.Int", token.Symbol)
}
return abi.Pack("safeTransferFrom",
from,
to,
id,
)
}
func (s *ERC721TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) { func (s *ERC721TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) {
ethClient, err := s.rpcClient.EthClient(fromNetwork.ChainID) ethClient, err := s.rpcClient.EthClient(fromNetwork.ChainID)
if err != nil { if err != nil {
return 0, err return 0, err
} }
var input []byte
value := new(big.Int) value := new(big.Int)
abi, err := abi.JSON(strings.NewReader(collectibles.CollectiblesMetaData.ABI)) input, err := s.PackTxInputData(fromNetwork, toNetwork, from, to, token, amountIn)
if err != nil {
return 0, err
}
id, success := big.NewInt(0).SetString(token.Symbol, 0)
if !success {
return 0, fmt.Errorf("failed to convert %s to big.Int", token.Symbol)
}
input, err = abi.Pack("safeTransferFrom",
from,
to,
id,
)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -24,12 +24,15 @@ import (
"github.com/status-im/status-go/eth-node/types" "github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/params" "github.com/status-im/status-go/params"
"github.com/status-im/status-go/rpc" "github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/services/wallet/bigint"
walletCommon "github.com/status-im/status-go/services/wallet/common" walletCommon "github.com/status-im/status-go/services/wallet/common"
"github.com/status-im/status-go/services/wallet/thirdparty" "github.com/status-im/status-go/services/wallet/thirdparty"
"github.com/status-im/status-go/services/wallet/token" "github.com/status-im/status-go/services/wallet/token"
"github.com/status-im/status-go/transactions" "github.com/status-im/status-go/transactions"
) )
const SevenDaysInSeconds = 604800
type HopTxArgs struct { type HopTxArgs struct {
transactions.SendTxArgs transactions.SendTxArgs
ChainID uint64 `json:"chainId"` ChainID uint64 `json:"chainId"`
@ -40,14 +43,14 @@ type HopTxArgs struct {
} }
type BonderFee struct { type BonderFee struct {
AmountIn *big.Int `json:"amountIn"` AmountIn *bigint.BigInt `json:"amountIn"`
Slippage float32 `json:"slippage"` Slippage float32 `json:"slippage"`
AmountOutMin *big.Int `json:"amountOutMin"` AmountOutMin *bigint.BigInt `json:"amountOutMin"`
DestinationAmountOutMin *big.Int `json:"destinationAmountOutMin"` DestinationAmountOutMin *bigint.BigInt `json:"destinationAmountOutMin"`
BonderFee *big.Int `json:"bonderFee"` BonderFee *bigint.BigInt `json:"bonderFee"`
EstimatedRecieved *big.Int `json:"estimatedRecieved"` EstimatedRecieved *bigint.BigInt `json:"estimatedRecieved"`
Deadline int64 `json:"deadline"` Deadline int64 `json:"deadline"`
DestinationDeadline int64 `json:"destinationDeadline"` DestinationDeadline int64 `json:"destinationDeadline"`
} }
func (bf *BonderFee) UnmarshalJSON(data []byte) error { func (bf *BonderFee) UnmarshalJSON(data []byte) error {
@ -70,21 +73,23 @@ func (bf *BonderFee) UnmarshalJSON(data []byte) error {
return err return err
} }
bf.AmountIn = new(big.Int) bf.AmountIn = &bigint.BigInt{Int: new(big.Int)}
bf.AmountIn.SetString(aux.AmountIn, 10) bf.AmountIn.SetString(aux.AmountIn, 10)
bf.AmountOutMin = new(big.Int) bf.AmountOutMin = &bigint.BigInt{Int: new(big.Int)}
bf.AmountOutMin.SetString(aux.AmountOutMin, 10) bf.AmountOutMin.SetString(aux.AmountOutMin, 10)
bf.DestinationAmountOutMin = new(big.Int) bf.DestinationAmountOutMin = &bigint.BigInt{Int: new(big.Int)}
bf.DestinationAmountOutMin.SetString(aux.DestinationAmountOutMin, 10) bf.DestinationAmountOutMin.SetString(aux.DestinationAmountOutMin, 10)
bf.BonderFee = new(big.Int) bf.BonderFee = &bigint.BigInt{Int: new(big.Int)}
bf.BonderFee.SetString(aux.BonderFee, 10) bf.BonderFee.SetString(aux.BonderFee, 10)
bf.EstimatedRecieved = new(big.Int) bf.EstimatedRecieved = &bigint.BigInt{Int: new(big.Int)}
bf.EstimatedRecieved.SetString(aux.EstimatedRecieved, 10) bf.EstimatedRecieved.SetString(aux.EstimatedRecieved, 10)
bf.Deadline = aux.Deadline
if aux.DestinationDeadline != nil { if aux.DestinationDeadline != nil {
bf.DestinationDeadline = *aux.DestinationDeadline bf.DestinationDeadline = *aux.DestinationDeadline
} }
@ -126,12 +131,41 @@ func (h *HopBridge) AvailableFor(from, to *params.Network, token *token.Token, t
return true, nil return true, nil
} }
func (h *HopBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) { func (h *HopBridge) PackTxInputData(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
var input []byte if fromNetwork.Layer == 1 {
value := new(big.Int) ABI, err := abi.JSON(strings.NewReader(hopBridge.HopBridgeABI))
if err != nil {
return []byte{}, err
}
now := time.Now() return ABI.Pack("sendToL2",
deadline := big.NewInt(now.Unix() + 604800) big.NewInt(int64(toNetwork.ChainID)),
to,
h.bonderFee.AmountIn.Int,
h.bonderFee.AmountOutMin.Int,
big.NewInt(h.bonderFee.Deadline),
common.HexToAddress("0x0"),
big.NewInt(0))
} else {
ABI, err := abi.JSON(strings.NewReader(hopWrapper.HopWrapperABI))
if err != nil {
return []byte{}, err
}
return ABI.Pack("swapAndSend",
big.NewInt(int64(toNetwork.ChainID)),
to,
h.bonderFee.AmountIn.Int,
h.bonderFee.BonderFee.Int,
h.bonderFee.AmountOutMin.Int,
big.NewInt(h.bonderFee.Deadline),
h.bonderFee.DestinationAmountOutMin.Int,
big.NewInt(h.bonderFee.DestinationDeadline))
}
}
func (h *HopBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) {
value := new(big.Int)
if token.IsNative() { if token.IsNative() {
value = amountIn value = amountIn
@ -144,43 +178,9 @@ func (h *HopBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.N
ctx := context.Background() ctx := context.Background()
if fromNetwork.Layer == 1 { input, err := h.PackTxInputData(fromNetwork, toNetwork, from, to, token, amountIn)
ABI, err := abi.JSON(strings.NewReader(hopBridge.HopBridgeABI)) if err != nil {
if err != nil { return 0, err
return 0, err
}
input, err = ABI.Pack("sendToL2",
big.NewInt(int64(toNetwork.ChainID)),
to,
amountIn,
big.NewInt(0),
deadline,
common.HexToAddress("0x0"),
big.NewInt(0))
if err != nil {
return 0, err
}
} else {
ABI, err := abi.JSON(strings.NewReader(hopWrapper.HopWrapperABI))
if err != nil {
return 0, err
}
input, err = ABI.Pack("swapAndSend",
big.NewInt(int64(toNetwork.ChainID)),
to,
amountIn,
big.NewInt(0),
big.NewInt(0),
deadline,
big.NewInt(0),
deadline)
if err != nil {
return 0, err
}
} }
ethClient, err := h.contractMaker.RPCClient.EthClient(fromNetwork.ChainID) ethClient, err := h.contractMaker.RPCClient.EthClient(fromNetwork.ChainID)
@ -286,14 +286,26 @@ func (h *HopBridge) sendToL2(chainID uint64, hopArgs *HopTxArgs, signerFn bind.S
if token.IsNative() { if token.IsNative() {
txOpts.Value = (*big.Int)(hopArgs.Amount) txOpts.Value = (*big.Int)(hopArgs.Amount)
} }
now := time.Now()
deadline := big.NewInt(now.Unix() + 604800) var (
deadline *big.Int
amountOutMin *big.Int
)
if h.bonderFee != nil {
deadline = big.NewInt(h.bonderFee.Deadline)
amountOutMin = h.bonderFee.AmountOutMin.Int
} else {
now := time.Now()
deadline = big.NewInt(now.Unix() + SevenDaysInSeconds)
}
tx, err = bridge.SendToL2( tx, err = bridge.SendToL2(
txOpts, txOpts,
big.NewInt(int64(hopArgs.ChainID)), big.NewInt(int64(hopArgs.ChainID)),
hopArgs.Recipient, hopArgs.Recipient,
hopArgs.Amount.ToInt(), hopArgs.Amount.ToInt(),
big.NewInt(0), amountOutMin,
deadline, deadline,
common.HexToAddress("0x0"), common.HexToAddress("0x0"),
big.NewInt(0), big.NewInt(0),
@ -317,14 +329,26 @@ func (h *HopBridge) swapAndSend(chainID uint64, hopArgs *HopTxArgs, signerFn bin
if token.IsNative() { if token.IsNative() {
txOpts.Value = (*big.Int)(hopArgs.Amount) txOpts.Value = (*big.Int)(hopArgs.Amount)
} }
now := time.Now()
deadline := big.NewInt(now.Unix() + 604800) var deadline *big.Int
amountOutMin := big.NewInt(0) amountOutMin := big.NewInt(0)
destinationDeadline := big.NewInt(now.Unix() + 604800) destinationDeadline := big.NewInt(0)
destinationAmountOutMin := big.NewInt(0) destinationAmountOutMin := big.NewInt(0)
if toNetwork.Layer == 1 { // https://docs.hop.exchange/v/developer-docs/smart-contracts/integration#l2-greater-than-l1-and-l2-greater-than-l2
destinationDeadline = big.NewInt(0) // Do not set `destinationAmountOutMin` and `destinationDeadline` when sending to L1 because there is no AMM on L1,
// otherwise the computed transferId will be invalid and the transfer will be unbondable. These parameters should be set to 0 when sending to L1.
if h.bonderFee != nil {
deadline = big.NewInt(h.bonderFee.Deadline)
amountOutMin = h.bonderFee.AmountOutMin.Int
destinationDeadline = big.NewInt(h.bonderFee.DestinationDeadline)
destinationAmountOutMin = h.bonderFee.DestinationAmountOutMin.Int
} else {
now := time.Now()
deadline = big.NewInt(now.Unix() + SevenDaysInSeconds)
if toNetwork.Layer != 1 {
destinationDeadline = big.NewInt(now.Unix() + SevenDaysInSeconds)
}
} }
tx, err = ammWrapper.SwapAndSend( tx, err = ammWrapper.SwapAndSend(
@ -372,16 +396,17 @@ func (h *HopBridge) CalculateFees(from, to *params.Network, token *token.Token,
return nil, nil, err return nil, nil, err
} }
h.bonderFee = &BonderFee{}
err = json.Unmarshal(response, h.bonderFee) err = json.Unmarshal(response, h.bonderFee)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
tokenFee := new(big.Int).Sub(h.bonderFee.AmountIn, h.bonderFee.EstimatedRecieved) tokenFee := new(big.Int).Sub(h.bonderFee.AmountIn.Int, h.bonderFee.EstimatedRecieved.Int)
return h.bonderFee.BonderFee, tokenFee, nil return h.bonderFee.BonderFee.Int, tokenFee, nil
} }
func (h *HopBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) { func (h *HopBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
return h.bonderFee.EstimatedRecieved, nil return h.bonderFee.EstimatedRecieved.Int, nil
} }

View File

@ -91,6 +91,11 @@ func (s *SwapParaswap) CalculateFees(from, to *params.Network, token *token.Toke
return big.NewInt(0), big.NewInt(0), nil return big.NewInt(0), big.NewInt(0), nil
} }
func (s *SwapParaswap) PackTxInputData(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
// not sure what we can do here since we're using the api to build the transaction
return []byte{}, nil
}
func (s *SwapParaswap) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) { func (s *SwapParaswap) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) {
priceRoute, err := s.paraswapClient.FetchPriceRoute(context.Background(), token.Address, token.Decimals, toToken.Address, toToken.Decimals, amountIn, from, to) priceRoute, err := s.paraswapClient.FetchPriceRoute(context.Background(), token.Address, token.Decimals, toToken.Address, toToken.Decimals, amountIn, from, to)
if err != nil { if err != nil {

View File

@ -40,11 +40,32 @@ func (s *TransferBridge) CalculateFees(from, to *params.Network, token *token.To
return big.NewInt(0), big.NewInt(0), nil return big.NewInt(0), big.NewInt(0), nil
} }
func (s *TransferBridge) PackTxInputData(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
if token.Symbol == "ETH" {
return []byte("eth_sendRawTransaction"), nil
} else {
abi, err := abi.JSON(strings.NewReader(ierc20.IERC20ABI))
if err != nil {
return []byte{}, err
}
return abi.Pack("transfer",
to,
amountIn,
)
}
}
func (s *TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) { func (s *TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, toToken *token.Token, amountIn *big.Int) (uint64, error) {
estimation := uint64(0) estimation := uint64(0)
var err error var err error
input, err := s.PackTxInputData(fromNetwork, toNetwork, from, to, token, amountIn)
if err != nil {
return 0, err
}
if token.Symbol == "ETH" { if token.Symbol == "ETH" {
estimation, err = s.transactor.EstimateGas(fromNetwork, from, to, amountIn, []byte("eth_sendRawTransaction")) estimation, err = s.transactor.EstimateGas(fromNetwork, from, to, amountIn, input)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -54,19 +75,6 @@ func (s *TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *par
return 0, err return 0, err
} }
abi, err := abi.JSON(strings.NewReader(ierc20.IERC20ABI))
if err != nil {
return 0, err
}
input, err := abi.Pack("transfer",
to,
amountIn,
)
if err != nil {
return 0, err
}
ctx := context.Background() ctx := context.Background()
msg := ethereum.CallMsg{ msg := ethereum.CallMsg{
@ -81,6 +89,7 @@ func (s *TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *par
} }
} }
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
return uint64(increasedEstimation), nil return uint64(increasedEstimation), nil
} }

View File

@ -9,7 +9,6 @@ import (
"github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/consensus/misc"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
gaspriceoracle "github.com/status-im/status-go/contracts/gas-price-oracle" 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"
@ -330,7 +329,12 @@ func (f *FeeManager) getFeeHistorySorted(chainID uint64) ([]*big.Int, error) {
return fees, nil return fees, nil
} }
func (f *FeeManager) GetL1Fee(ctx context.Context, chainID uint64, tx *ethTypes.Transaction) (uint64, error) { // Returns L1 fee for placing a transaction to L1 chain, appicable only for txs made from L2.
func (f *FeeManager) GetL1Fee(ctx context.Context, chainID uint64, input []byte) (uint64, error) {
if chainID == common.EthereumMainnet || chainID == common.EthereumSepolia && chainID != common.EthereumGoerli {
return 0, nil
}
ethClient, err := f.RPCClient.EthClient(chainID) ethClient, err := f.RPCClient.EthClient(chainID)
if err != nil { if err != nil {
return 0, err return 0, err
@ -348,12 +352,7 @@ func (f *FeeManager) GetL1Fee(ctx context.Context, chainID uint64, tx *ethTypes.
callOpt := &bind.CallOpts{} callOpt := &bind.CallOpts{}
data, err := tx.MarshalBinary() result, err := contract.GetL1Fee(callOpt, input)
if err != nil {
return 0, err
}
result, err := contract.GetL1Fee(callOpt, data)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View File

@ -591,7 +591,7 @@ func (r *Router) SuggestedRoutes(
} }
} }
gasLimit := uint64(0) gasLimit := uint64(0)
if sendType.isTransfer() { if sendType.isTransfer(false) {
gasLimit, err = bridge.EstimateGas(network, dest, addrFrom, addrTo, token, toToken, amountIn) gasLimit, err = bridge.EstimateGas(network, dest, addrFrom, addrTo, token, toToken, amountIn)
if err != nil { if err != nil {
continue continue
@ -608,12 +608,12 @@ func (r *Router) SuggestedRoutes(
var l1GasFeeWei uint64 var l1GasFeeWei uint64
if sendType.needL1Fee() { if sendType.needL1Fee() {
tx, err := bridge.BuildTx(network, dest, addrFrom, addrTo, token, amountIn, bonderFees) txInputData, err := bridge.PackTxInputData(network, dest, addrFrom, addrTo, token, amountIn)
if err != nil { if err != nil {
continue continue
} }
l1GasFeeWei, _ = r.feesManager.GetL1Fee(ctx, network.ChainID, tx) l1GasFeeWei, _ = r.feesManager.GetL1Fee(ctx, network.ChainID, txInputData)
l1GasFeeWei += l1ApprovalFee l1GasFeeWei += l1ApprovalFee
} }

View File

@ -83,8 +83,11 @@ func (s SendType) FindToken(tokenManager *token.Manager, collectibles *collectib
} }
} }
func (s SendType) isTransfer() bool { func (s SendType) isTransfer(routerV2Logic bool) bool {
return s == Transfer || s == Swap || s.IsCollectiblesTransfer() return s == Transfer ||
s == Bridge && routerV2Logic ||
s == Swap ||
s.IsCollectiblesTransfer()
} }
func (s SendType) needL1Fee() bool { func (s SendType) needL1Fee() bool {

View File

@ -266,12 +266,8 @@ func findBestV2(routes [][]*PathV2, tokenPrice float64, nativeChainTokenPrice fl
for _, route := range routes { for _, route := range routes {
currentCost := big.NewFloat(0) currentCost := big.NewFloat(0)
for _, path := range route { for _, path := range route {
if path.FromToken.IsNative() { path.requiredTokenBalance = new(big.Int).Set(path.AmountIn.ToInt())
path.requiredNativeBalance = new(big.Int).Set(path.AmountIn.ToInt()) path.requiredNativeBalance = big.NewInt(0)
} else {
path.requiredTokenBalance = new(big.Int).Set(path.AmountIn.ToInt())
path.requiredNativeBalance = big.NewInt(0)
}
// ecaluate the cost of the path // ecaluate the cost of the path
pathCost := big.NewFloat(0) pathCost := big.NewFloat(0)
@ -434,7 +430,7 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
} }
gasLimit := uint64(0) gasLimit := uint64(0)
if input.SendType.isTransfer() { if input.SendType.isTransfer(true) {
gasLimit, err = bridge.EstimateGas(network, dest, input.AddrFrom, input.AddrTo, token, toToken, amountToSend) gasLimit, err = bridge.EstimateGas(network, dest, input.AddrFrom, input.AddrTo, token, toToken, amountToSend)
if err != nil { if err != nil {
continue continue
@ -452,12 +448,12 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
var l1FeeWei uint64 var l1FeeWei uint64
if input.SendType.needL1Fee() { if input.SendType.needL1Fee() {
tx, err := bridge.BuildTx(network, dest, input.AddrFrom, input.AddrTo, token, amountToSend, bonderFees) txInputData, err := bridge.PackTxInputData(network, dest, input.AddrFrom, input.AddrTo, token, amountToSend)
if err != nil { if err != nil {
continue continue
} }
l1FeeWei, _ = r.feesManager.GetL1Fee(ctx, network.ChainID, tx) l1FeeWei, _ = r.feesManager.GetL1Fee(ctx, network.ChainID, txInputData)
} }
baseFee, err := r.feesManager.getBaseFee(ctx, client) baseFee, err := r.feesManager.getBaseFee(ctx, client)