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:
parent
4e51b5ba24
commit
c74931c333
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue