chore_: ens register improvements
This commit is contained in:
parent
2149035619
commit
11f83780d1
|
@ -1,6 +1,7 @@
|
|||
package bridge
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
|
||||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
|
@ -8,15 +9,33 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/eth-node/crypto"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/services/wallet/token"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
)
|
||||
|
||||
var ZeroAddress = common.Address{}
|
||||
var (
|
||||
ZeroAddress = common.Address{}
|
||||
ZeroBigIntValue = big.NewInt(0)
|
||||
)
|
||||
|
||||
const IncreaseEstimatedGasFactor = 1.1
|
||||
const (
|
||||
IncreaseEstimatedGasFactor = 1.1
|
||||
|
||||
EthSymbol = "ETH"
|
||||
SntSymbol = "SNT"
|
||||
SttSymbol = "STT"
|
||||
|
||||
TransferName = "Transfer"
|
||||
HopName = "Hop"
|
||||
CBridgeName = "CBridge"
|
||||
SwapParaswapName = "Paraswap"
|
||||
ERC721TransferName = "ERC721Transfer"
|
||||
ERC1155TransferName = "ERC1155Transfer"
|
||||
ENSRegisterName = "ENSRegister"
|
||||
)
|
||||
|
||||
func getSigner(chainID uint64, from types.Address, verifiedAccount *account.SelectedExtKey) bind.SignerFn {
|
||||
return func(addr common.Address, tx *ethTypes.Transaction) (*ethTypes.Transaction, error) {
|
||||
|
@ -100,19 +119,55 @@ func (t *TransactionBridge) Data() types.HexBytes {
|
|||
return types.HexBytes("")
|
||||
}
|
||||
|
||||
type BridgeParams struct {
|
||||
FromChain *params.Network
|
||||
ToChain *params.Network
|
||||
FromAddr common.Address
|
||||
ToAddr common.Address
|
||||
FromToken *token.Token
|
||||
ToToken *token.Token
|
||||
AmountIn *big.Int
|
||||
|
||||
// extra params
|
||||
BonderFee *big.Int
|
||||
Username string
|
||||
PublicKey string
|
||||
}
|
||||
|
||||
type Bridge interface {
|
||||
// returns the name of the bridge
|
||||
Name() string
|
||||
// checks if the bridge is available for the given networks/tokens
|
||||
AvailableFor(from *params.Network, to *params.Network, token *token.Token, toToken *token.Token) (bool, error)
|
||||
AvailableFor(params BridgeParams) (bool, error)
|
||||
// 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(params BridgeParams) (*big.Int, *big.Int, error)
|
||||
// Pack the method for sending tx and method call's data
|
||||
PackTxInputData(contractType string, 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)
|
||||
CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error)
|
||||
PackTxInputData(params BridgeParams, contractType string) ([]byte, error)
|
||||
EstimateGas(params BridgeParams) (uint64, error)
|
||||
CalculateAmountOut(params BridgeParams) (*big.Int, error)
|
||||
Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (types.Hash, error)
|
||||
GetContractAddress(network *params.Network, token *token.Token) (common.Address, error)
|
||||
GetContractAddress(params BridgeParams) (common.Address, error)
|
||||
BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, error)
|
||||
BuildTx(fromNetwork, toNetwork *params.Network, fromAddress common.Address, toAddress common.Address, token *token.Token, amountIn *big.Int, bonderFee *big.Int) (*ethTypes.Transaction, error)
|
||||
BuildTx(params BridgeParams) (*ethTypes.Transaction, error)
|
||||
}
|
||||
|
||||
func extractCoordinates(pubkey string) ([32]byte, [32]byte) {
|
||||
x, _ := hex.DecodeString(pubkey[4:68])
|
||||
y, _ := hex.DecodeString(pubkey[68:132])
|
||||
|
||||
var xByte [32]byte
|
||||
copy(xByte[:], x)
|
||||
|
||||
var yByte [32]byte
|
||||
copy(yByte[:], y)
|
||||
|
||||
return xByte, yByte
|
||||
}
|
||||
|
||||
func usernameToLabel(username string) [32]byte {
|
||||
usernameHashed := crypto.Keccak256([]byte(username))
|
||||
var label [32]byte
|
||||
copy(label[:], usernameHashed)
|
||||
|
||||
return label
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ const (
|
|||
testBaseURL = "https://cbridge-v2-test.celer.network"
|
||||
|
||||
maxSlippage = uint32(1000)
|
||||
ethSymbol = "ETH"
|
||||
)
|
||||
|
||||
type CBridgeTxArgs struct {
|
||||
|
@ -64,7 +63,7 @@ func NewCbridge(rpcClient *rpc.Client, transactor transactions.TransactorIface,
|
|||
}
|
||||
|
||||
func (s *CBridge) Name() string {
|
||||
return "CBridge"
|
||||
return CBridgeName
|
||||
}
|
||||
|
||||
func (s *CBridge) estimateAmt(from, to *params.Network, amountIn *big.Int, symbol string) (*cbridge.EstimateAmtResponse, error) {
|
||||
|
@ -127,12 +126,12 @@ func (s *CBridge) getTransferConfig(isTest bool) (*cbridge.GetTransferConfigsRes
|
|||
return &res, nil
|
||||
}
|
||||
|
||||
func (s *CBridge) AvailableFor(from, to *params.Network, token *token.Token, toToken *token.Token) (bool, error) {
|
||||
if from.ChainID == to.ChainID || toToken != nil {
|
||||
func (s *CBridge) AvailableFor(params BridgeParams) (bool, error) {
|
||||
if params.FromChain.ChainID == params.ToChain.ChainID || params.ToToken != nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
transferConfig, err := s.getTransferConfig(from.IsTest)
|
||||
transferConfig, err := s.getTransferConfig(params.FromChain.IsTest)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
@ -143,11 +142,11 @@ func (s *CBridge) AvailableFor(from, to *params.Network, token *token.Token, toT
|
|||
var fromAvailable *cbridge.Chain
|
||||
var toAvailable *cbridge.Chain
|
||||
for _, chain := range transferConfig.Chains {
|
||||
if uint64(chain.GetId()) == from.ChainID && chain.GasTokenSymbol == ethSymbol {
|
||||
if uint64(chain.GetId()) == params.FromChain.ChainID && chain.GasTokenSymbol == EthSymbol {
|
||||
fromAvailable = chain
|
||||
}
|
||||
|
||||
if uint64(chain.GetId()) == to.ChainID && chain.GasTokenSymbol == ethSymbol {
|
||||
if uint64(chain.GetId()) == params.ToChain.ChainID && chain.GasTokenSymbol == EthSymbol {
|
||||
toAvailable = chain
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +161,7 @@ func (s *CBridge) AvailableFor(from, to *params.Network, token *token.Token, toT
|
|||
}
|
||||
|
||||
for _, tokenInfo := range transferConfig.ChainToken[fromAvailable.GetId()].Token {
|
||||
if tokenInfo.Token.Symbol == token.Symbol {
|
||||
if tokenInfo.Token.Symbol == params.FromToken.Symbol {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
|
@ -173,19 +172,21 @@ func (s *CBridge) AvailableFor(from, to *params.Network, token *token.Token, toT
|
|||
|
||||
found = false
|
||||
for _, tokenInfo := range transferConfig.ChainToken[toAvailable.GetId()].Token {
|
||||
if tokenInfo.Token.Symbol == token.Symbol {
|
||||
if tokenInfo.Token.Symbol == params.FromToken.Symbol {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *CBridge) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) {
|
||||
amt, err := s.estimateAmt(from, to, amountIn, token.Symbol)
|
||||
func (s *CBridge) CalculateFees(params BridgeParams) (*big.Int, *big.Int, error) {
|
||||
amt, err := s.estimateAmt(params.FromChain, params.ToChain, params.AmountIn, params.FromToken.Symbol)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -201,46 +202,46 @@ func (s *CBridge) CalculateFees(from, to *params.Network, token *token.Token, am
|
|||
return big.NewInt(0), new(big.Int).Add(baseFee, percFee), nil
|
||||
}
|
||||
|
||||
func (c *CBridge) PackTxInputData(contractType string, fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
|
||||
func (c *CBridge) PackTxInputData(params BridgeParams, contractType string) ([]byte, error) {
|
||||
abi, err := abi.JSON(strings.NewReader(celer.CelerABI))
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
if token.IsNative() {
|
||||
if params.FromToken.IsNative() {
|
||||
return abi.Pack("sendNative",
|
||||
to,
|
||||
amountIn,
|
||||
toNetwork.ChainID,
|
||||
params.ToAddr,
|
||||
params.AmountIn,
|
||||
params.ToChain.ChainID,
|
||||
uint64(time.Now().UnixMilli()),
|
||||
maxSlippage,
|
||||
)
|
||||
} else {
|
||||
return abi.Pack("send",
|
||||
to,
|
||||
token.Address,
|
||||
amountIn,
|
||||
toNetwork.ChainID,
|
||||
params.ToAddr,
|
||||
params.FromToken.Address,
|
||||
params.AmountIn,
|
||||
params.ToChain.ChainID,
|
||||
uint64(time.Now().UnixMilli()),
|
||||
maxSlippage,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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 (s *CBridge) EstimateGas(params BridgeParams) (uint64, error) {
|
||||
value := new(big.Int)
|
||||
|
||||
input, err := s.PackTxInputData("", fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
input, err := s.PackTxInputData(params, "")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
contractAddress, err := s.GetContractAddress(fromNetwork, nil)
|
||||
contractAddress, err := s.GetContractAddress(params)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
ethClient, err := s.rpcClient.EthClient(fromNetwork.ChainID)
|
||||
ethClient, err := s.rpcClient.EthClient(params.FromChain.ChainID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -248,7 +249,7 @@ func (s *CBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Net
|
|||
ctx := context.Background()
|
||||
|
||||
msg := ethereum.CallMsg{
|
||||
From: from,
|
||||
From: params.FromAddr,
|
||||
To: &contractAddress,
|
||||
Value: value,
|
||||
Data: input,
|
||||
|
@ -256,7 +257,7 @@ func (s *CBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Net
|
|||
|
||||
estimation, err := ethClient.EstimateGas(ctx, msg)
|
||||
if err != nil {
|
||||
if !token.IsNative() {
|
||||
if !params.FromToken.IsNative() {
|
||||
// TODO: this is a temporary solution until we find a better way to estimate the gas
|
||||
// hardcoding the estimation for other than ETH, cause we cannot get a proper estimation without having an approval placed first
|
||||
// this is an error we're facing otherwise: `execution reverted: ERC20: transfer amount exceeds allowance`
|
||||
|
@ -269,29 +270,29 @@ func (s *CBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.Net
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *CBridge) BuildTx(fromNetwork, toNetwork *params.Network, fromAddress common.Address, toAddress common.Address, token *token.Token, amountIn *big.Int, bonderFee *big.Int) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(toAddress)
|
||||
func (s *CBridge) BuildTx(params BridgeParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
sendArgs := &TransactionBridge{
|
||||
CbridgeTx: &CBridgeTxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(fromAddress),
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(amountIn),
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
ChainID: toNetwork.ChainID,
|
||||
Symbol: token.Symbol,
|
||||
Recipient: toAddress,
|
||||
Amount: (*hexutil.Big)(amountIn),
|
||||
ChainID: params.ToChain.ChainID,
|
||||
Symbol: params.FromToken.Symbol,
|
||||
Recipient: params.ToAddr,
|
||||
Amount: (*hexutil.Big)(params.AmountIn),
|
||||
},
|
||||
ChainID: fromNetwork.ChainID,
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
}
|
||||
|
||||
func (s *CBridge) GetContractAddress(network *params.Network, token *token.Token) (common.Address, error) {
|
||||
transferConfig, err := s.getTransferConfig(network.IsTest)
|
||||
func (s *CBridge) GetContractAddress(params BridgeParams) (common.Address, error) {
|
||||
transferConfig, err := s.getTransferConfig(params.FromChain.IsTest)
|
||||
if err != nil {
|
||||
return common.Address{}, err
|
||||
}
|
||||
|
@ -300,7 +301,7 @@ func (s *CBridge) GetContractAddress(network *params.Network, token *token.Token
|
|||
}
|
||||
|
||||
for _, chain := range transferConfig.Chains {
|
||||
if uint64(chain.Id) == network.ChainID {
|
||||
if uint64(chain.Id) == params.FromChain.ChainID {
|
||||
return common.HexToAddress(chain.ContractAddr), nil
|
||||
}
|
||||
}
|
||||
|
@ -309,15 +310,17 @@ func (s *CBridge) GetContractAddress(network *params.Network, token *token.Token
|
|||
}
|
||||
|
||||
func (s *CBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerFn) (*ethTypes.Transaction, error) {
|
||||
fromNetwork := s.rpcClient.NetworkManager.Find(sendArgs.ChainID)
|
||||
if fromNetwork == nil {
|
||||
fromChain := s.rpcClient.NetworkManager.Find(sendArgs.ChainID)
|
||||
if fromChain == nil {
|
||||
return nil, errors.New("network not found")
|
||||
}
|
||||
token := s.tokenManager.FindToken(fromNetwork, sendArgs.CbridgeTx.Symbol)
|
||||
token := s.tokenManager.FindToken(fromChain, sendArgs.CbridgeTx.Symbol)
|
||||
if token == nil {
|
||||
return nil, errors.New("token not found")
|
||||
}
|
||||
addrs, err := s.GetContractAddress(fromNetwork, nil)
|
||||
addrs, err := s.GetContractAddress(BridgeParams{
|
||||
FromChain: fromChain,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -367,8 +370,8 @@ func (s *CBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Trans
|
|||
return s.sendOrBuild(sendArgs, nil)
|
||||
}
|
||||
|
||||
func (s *CBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
||||
amt, err := s.estimateAmt(from, to, amountIn, symbol)
|
||||
func (s *CBridge) CalculateAmountOut(params BridgeParams) (*big.Int, error) {
|
||||
amt, err := s.estimateAmt(params.FromChain, params.ToChain, params.AmountIn, params.FromToken.Symbol)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
package bridge
|
||||
|
||||
import (
|
||||
"context"
|
||||
"math/big"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts"
|
||||
"github.com/status-im/status-go/contracts/registrar"
|
||||
"github.com/status-im/status-go/contracts/snt"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/services/ens"
|
||||
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
)
|
||||
|
||||
type ENSRegisterBridge struct {
|
||||
contractMaker *contracts.ContractMaker
|
||||
transactor transactions.TransactorIface
|
||||
ensService *ens.Service
|
||||
}
|
||||
|
||||
func NewENSRegisterBridge(rpcClient *rpc.Client, transactor transactions.TransactorIface, ensService *ens.Service) *ENSRegisterBridge {
|
||||
return &ENSRegisterBridge{
|
||||
contractMaker: &contracts.ContractMaker{
|
||||
RPCClient: rpcClient,
|
||||
},
|
||||
// rpcClient: rpcClient,
|
||||
transactor: transactor,
|
||||
ensService: ensService,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) Name() string {
|
||||
return ENSRegisterName
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) GetPriceForRegisteringEnsName(chainID uint64) (*big.Int, error) {
|
||||
registryAddr, err := s.ensService.API().GetRegistrarAddress(context.Background(), chainID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
registrar, err := s.contractMaker.NewUsernameRegistrar(chainID, registryAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
callOpts := &bind.CallOpts{Context: context.Background(), Pending: false}
|
||||
return registrar.GetPrice(callOpts)
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) AvailableFor(params BridgeParams) (bool, error) {
|
||||
return params.FromChain.ChainID == walletCommon.EthereumMainnet || params.FromChain.ChainID == walletCommon.EthereumSepolia, nil
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) CalculateFees(params BridgeParams) (*big.Int, *big.Int, error) {
|
||||
return big.NewInt(0), big.NewInt(0), nil
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) PackTxInputData(params BridgeParams, contractType string) ([]byte, error) {
|
||||
price, err := s.GetPriceForRegisteringEnsName(params.FromChain.ChainID)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI))
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
x, y := extractCoordinates(params.PublicKey)
|
||||
extraData, err := registrarABI.Pack("register", usernameToLabel(params.Username), params.FromAddr, x, y)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
sntABI, err := abi.JSON(strings.NewReader(snt.SNTABI))
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
registryAddr, err := s.ensService.API().GetRegistrarAddress(context.Background(), params.FromChain.ChainID)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
return sntABI.Pack("approveAndCall", registryAddr, price, extraData)
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) EstimateGas(params BridgeParams) (uint64, error) {
|
||||
contractAddress, err := s.GetContractAddress(params)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
input, err := s.PackTxInputData(params, "")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
msg := ethereum.CallMsg{
|
||||
From: params.FromAddr,
|
||||
To: &contractAddress,
|
||||
Value: big.NewInt(0),
|
||||
Data: input,
|
||||
}
|
||||
|
||||
estimation, err := ethClient.EstimateGas(context.Background(), msg)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
|
||||
|
||||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) BuildTx(params BridgeParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
inputData, err := s.PackTxInputData(params, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sendArgs := &TransactionBridge{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(ZeroBigIntValue),
|
||||
Data: inputData,
|
||||
},
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) Send(sendArgs *TransactionBridge, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
|
||||
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, *sendArgs.TransferTx, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Transaction, error) {
|
||||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) CalculateAmountOut(params BridgeParams) (*big.Int, error) {
|
||||
return params.AmountIn, nil
|
||||
}
|
||||
|
||||
func (s *ENSRegisterBridge) GetContractAddress(params BridgeParams) (common.Address, error) {
|
||||
return snt.ContractAddress(params.FromChain.ChainID)
|
||||
}
|
|
@ -15,9 +15,7 @@ import (
|
|||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts/ierc1155"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/services/wallet/token"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
)
|
||||
|
||||
|
@ -38,53 +36,53 @@ func NewERC1155TransferBridge(rpcClient *rpc.Client, transactor transactions.Tra
|
|||
}
|
||||
|
||||
func (s *ERC1155TransferBridge) Name() string {
|
||||
return "ERC1155Transfer"
|
||||
return ERC1155TransferName
|
||||
}
|
||||
|
||||
func (s *ERC1155TransferBridge) AvailableFor(from, to *params.Network, token *token.Token, toToken *token.Token) (bool, error) {
|
||||
return from.ChainID == to.ChainID && toToken == nil, nil
|
||||
func (s *ERC1155TransferBridge) AvailableFor(params BridgeParams) (bool, error) {
|
||||
return params.FromChain.ChainID == params.ToChain.ChainID && params.ToToken == nil, nil
|
||||
}
|
||||
|
||||
func (s *ERC1155TransferBridge) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) {
|
||||
func (s *ERC1155TransferBridge) CalculateFees(params BridgeParams) (*big.Int, *big.Int, error) {
|
||||
return big.NewInt(0), big.NewInt(0), nil
|
||||
}
|
||||
|
||||
func (s *ERC1155TransferBridge) PackTxInputData(contractType string, fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
|
||||
func (s *ERC1155TransferBridge) PackTxInputData(params BridgeParams, contractType string) ([]byte, error) {
|
||||
abi, err := abi.JSON(strings.NewReader(ierc1155.Ierc1155ABI))
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
id, success := big.NewInt(0).SetString(token.Symbol, 0)
|
||||
id, success := big.NewInt(0).SetString(params.FromToken.Symbol, 0)
|
||||
if !success {
|
||||
return []byte{}, fmt.Errorf("failed to convert %s to big.Int", token.Symbol)
|
||||
return []byte{}, fmt.Errorf("failed to convert %s to big.Int", params.FromToken.Symbol)
|
||||
}
|
||||
|
||||
return abi.Pack("safeTransferFrom",
|
||||
from,
|
||||
to,
|
||||
params.FromAddr,
|
||||
params.ToAddr,
|
||||
id,
|
||||
amountIn,
|
||||
params.AmountIn,
|
||||
[]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)
|
||||
func (s *ERC1155TransferBridge) EstimateGas(params BridgeParams) (uint64, error) {
|
||||
ethClient, err := s.rpcClient.EthClient(params.FromChain.ChainID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
value := new(big.Int)
|
||||
|
||||
input, err := s.PackTxInputData("", fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
input, err := s.PackTxInputData(params, "")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
msg := ethereum.CallMsg{
|
||||
From: from,
|
||||
To: &token.Address,
|
||||
From: params.FromAddr,
|
||||
To: ¶ms.FromToken.Address,
|
||||
Value: value,
|
||||
Data: input,
|
||||
}
|
||||
|
@ -97,28 +95,28 @@ func (s *ERC1155TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwo
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *ERC1155TransferBridge) BuildTx(network, _ *params.Network, fromAddress common.Address, toAddress common.Address, token *token.Token, amountIn *big.Int, _ *big.Int) (*ethTypes.Transaction, error) {
|
||||
contractAddress := types.Address(token.Address)
|
||||
func (s *ERC1155TransferBridge) BuildTx(params BridgeParams) (*ethTypes.Transaction, error) {
|
||||
contractAddress := types.Address(params.FromToken.Address)
|
||||
|
||||
// We store ERC1155 Token ID using big.Int.String() in token.Symbol
|
||||
tokenID, success := new(big.Int).SetString(token.Symbol, 10)
|
||||
tokenID, success := new(big.Int).SetString(params.FromToken.Symbol, 10)
|
||||
if !success {
|
||||
return nil, fmt.Errorf("failed to convert ERC1155's Symbol %s to big.Int", token.Symbol)
|
||||
return nil, fmt.Errorf("failed to convert ERC1155's Symbol %s to big.Int", params.FromToken.Symbol)
|
||||
}
|
||||
|
||||
sendArgs := &TransactionBridge{
|
||||
ERC1155TransferTx: &ERC1155TransferTxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(fromAddress),
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &contractAddress,
|
||||
Value: (*hexutil.Big)(amountIn),
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
TokenID: (*hexutil.Big)(tokenID),
|
||||
Recipient: toAddress,
|
||||
Amount: (*hexutil.Big)(amountIn),
|
||||
Recipient: params.ToAddr,
|
||||
Amount: (*hexutil.Big)(params.AmountIn),
|
||||
},
|
||||
ChainID: network.ChainID,
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
|
@ -165,10 +163,10 @@ func (s *ERC1155TransferBridge) BuildTransaction(sendArgs *TransactionBridge) (*
|
|||
return s.sendOrBuild(sendArgs, nil)
|
||||
}
|
||||
|
||||
func (s *ERC1155TransferBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
||||
return amountIn, nil
|
||||
func (s *ERC1155TransferBridge) CalculateAmountOut(params BridgeParams) (*big.Int, error) {
|
||||
return params.AmountIn, nil
|
||||
}
|
||||
|
||||
func (s *ERC1155TransferBridge) GetContractAddress(network *params.Network, token *token.Token) (common.Address, error) {
|
||||
return token.Address, nil
|
||||
func (s *ERC1155TransferBridge) GetContractAddress(params BridgeParams) (common.Address, error) {
|
||||
return params.FromToken.Address, nil
|
||||
}
|
||||
|
|
|
@ -15,9 +15,7 @@ import (
|
|||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts/community-tokens/collectibles"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/services/wallet/token"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
)
|
||||
|
||||
|
@ -37,51 +35,51 @@ func NewERC721TransferBridge(rpcClient *rpc.Client, transactor transactions.Tran
|
|||
}
|
||||
|
||||
func (s *ERC721TransferBridge) Name() string {
|
||||
return "ERC721Transfer"
|
||||
return ERC721TransferName
|
||||
}
|
||||
|
||||
func (s *ERC721TransferBridge) AvailableFor(from, to *params.Network, token *token.Token, toToken *token.Token) (bool, error) {
|
||||
return from.ChainID == to.ChainID && toToken == nil, nil
|
||||
func (s *ERC721TransferBridge) AvailableFor(params BridgeParams) (bool, error) {
|
||||
return params.FromChain.ChainID == params.ToChain.ChainID && params.ToToken == nil, nil
|
||||
}
|
||||
|
||||
func (s *ERC721TransferBridge) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) {
|
||||
func (s *ERC721TransferBridge) CalculateFees(params BridgeParams) (*big.Int, *big.Int, error) {
|
||||
return big.NewInt(0), big.NewInt(0), nil
|
||||
}
|
||||
|
||||
func (s *ERC721TransferBridge) PackTxInputData(contractType string, fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
|
||||
func (s *ERC721TransferBridge) PackTxInputData(params BridgeParams, contractType string) ([]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)
|
||||
id, success := big.NewInt(0).SetString(params.FromToken.Symbol, 0)
|
||||
if !success {
|
||||
return []byte{}, fmt.Errorf("failed to convert %s to big.Int", token.Symbol)
|
||||
return []byte{}, fmt.Errorf("failed to convert %s to big.Int", params.FromToken.Symbol)
|
||||
}
|
||||
|
||||
return abi.Pack("safeTransferFrom",
|
||||
from,
|
||||
to,
|
||||
params.FromAddr,
|
||||
params.ToAddr,
|
||||
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) {
|
||||
ethClient, err := s.rpcClient.EthClient(fromNetwork.ChainID)
|
||||
func (s *ERC721TransferBridge) EstimateGas(params BridgeParams) (uint64, error) {
|
||||
ethClient, err := s.rpcClient.EthClient(params.FromChain.ChainID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
value := new(big.Int)
|
||||
|
||||
input, err := s.PackTxInputData("", fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
input, err := s.PackTxInputData(params, "")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
msg := ethereum.CallMsg{
|
||||
From: from,
|
||||
To: &token.Address,
|
||||
From: params.FromAddr,
|
||||
To: ¶ms.FromToken.Address,
|
||||
Value: value,
|
||||
Data: input,
|
||||
}
|
||||
|
@ -90,31 +88,32 @@ func (s *ERC721TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwor
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
|
||||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *ERC721TransferBridge) BuildTx(network, _ *params.Network, fromAddress common.Address, toAddress common.Address, token *token.Token, amountIn *big.Int, _ *big.Int) (*ethTypes.Transaction, error) {
|
||||
contractAddress := types.Address(token.Address)
|
||||
func (s *ERC721TransferBridge) BuildTx(params BridgeParams) (*ethTypes.Transaction, error) {
|
||||
contractAddress := types.Address(params.FromToken.Address)
|
||||
|
||||
// We store ERC721 Token ID using big.Int.String() in token.Symbol
|
||||
tokenID, success := new(big.Int).SetString(token.Symbol, 10)
|
||||
tokenID, success := new(big.Int).SetString(params.FromToken.Symbol, 10)
|
||||
if !success {
|
||||
return nil, fmt.Errorf("failed to convert ERC721's Symbol %s to big.Int", token.Symbol)
|
||||
return nil, fmt.Errorf("failed to convert ERC721's Symbol %s to big.Int", params.FromToken.Symbol)
|
||||
}
|
||||
|
||||
sendArgs := &TransactionBridge{
|
||||
ERC721TransferTx: &ERC721TransferTxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(fromAddress),
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &contractAddress,
|
||||
Value: (*hexutil.Big)(amountIn),
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
TokenID: (*hexutil.Big)(tokenID),
|
||||
Recipient: toAddress,
|
||||
Recipient: params.ToAddr,
|
||||
},
|
||||
ChainID: network.ChainID,
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
|
@ -139,6 +138,7 @@ func (s *ERC721TransferBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn
|
|||
argNonce := hexutil.Uint64(nonce)
|
||||
sendArgs.ERC721TransferTx.Nonce = &argNonce
|
||||
txOpts := sendArgs.ERC721TransferTx.ToTransactOpts(signerFn)
|
||||
|
||||
tx, err = contract.SafeTransferFrom(txOpts, common.Address(sendArgs.ERC721TransferTx.From),
|
||||
sendArgs.ERC721TransferTx.Recipient,
|
||||
sendArgs.ERC721TransferTx.TokenID.ToInt())
|
||||
|
@ -157,10 +157,10 @@ func (s *ERC721TransferBridge) BuildTransaction(sendArgs *TransactionBridge) (*e
|
|||
return s.sendOrBuild(sendArgs, nil)
|
||||
}
|
||||
|
||||
func (s *ERC721TransferBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
||||
return amountIn, nil
|
||||
func (s *ERC721TransferBridge) CalculateAmountOut(params BridgeParams) (*big.Int, error) {
|
||||
return params.AmountIn, nil
|
||||
}
|
||||
|
||||
func (s *ERC721TransferBridge) GetContractAddress(network *params.Network, token *token.Token) (common.Address, error) {
|
||||
return token.Address, nil
|
||||
func (s *ERC721TransferBridge) GetContractAddress(params BridgeParams) (common.Address, error) {
|
||||
return params.FromToken.Address, nil
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
hopL2CctpImplementation "github.com/status-im/status-go/contracts/hop/l2Contracts/l2CctpImplementation"
|
||||
hopL2OptimismBridge "github.com/status-im/status-go/contracts/hop/l2Contracts/l2OptimismBridge"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/rpc/chain"
|
||||
"github.com/status-im/status-go/services/wallet/bigint"
|
||||
|
@ -124,14 +123,14 @@ func NewHopBridge(rpcClient *rpc.Client, transactor transactions.TransactorIface
|
|||
}
|
||||
|
||||
func (h *HopBridge) Name() string {
|
||||
return "Hop"
|
||||
return HopName
|
||||
}
|
||||
|
||||
func (h *HopBridge) AvailableFor(from, to *params.Network, token *token.Token, toToken *token.Token) (bool, error) {
|
||||
func (h *HopBridge) AvailableFor(params BridgeParams) (bool, error) {
|
||||
// We chcek if the contract is available on the network for the token
|
||||
_, err := h.GetContractAddress(from, token)
|
||||
_, err := h.GetContractAddress(params)
|
||||
// toToken is not nil only if the send type is Swap
|
||||
return err == nil && toToken == nil, nil
|
||||
return err == nil && params.ToToken == nil, nil
|
||||
}
|
||||
|
||||
func (c *HopBridge) getAppropriateABI(contractType string, chainID uint64, token *token.Token) (abi.ABI, error) {
|
||||
|
@ -164,51 +163,51 @@ func (c *HopBridge) getAppropriateABI(contractType string, chainID uint64, token
|
|||
return abi.ABI{}, errors.New("not available for contract type")
|
||||
}
|
||||
|
||||
func (h *HopBridge) PackTxInputData(contractType string, fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
|
||||
abi, err := h.getAppropriateABI(contractType, fromNetwork.ChainID, token)
|
||||
func (h *HopBridge) PackTxInputData(params BridgeParams, contractType string) ([]byte, error) {
|
||||
abi, err := h.getAppropriateABI(contractType, params.FromChain.ChainID, params.FromToken)
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
|
||||
switch contractType {
|
||||
case hop.CctpL1Bridge:
|
||||
return h.packCctpL1BridgeTx(abi, toNetwork.ChainID, to)
|
||||
return h.packCctpL1BridgeTx(abi, params.ToChain.ChainID, params.ToAddr)
|
||||
case hop.L1Bridge:
|
||||
return h.packL1BridgeTx(abi, toNetwork.ChainID, to)
|
||||
return h.packL1BridgeTx(abi, params.ToChain.ChainID, params.ToAddr)
|
||||
case hop.L2AmmWrapper:
|
||||
return h.packL2AmmWrapperTx(abi, toNetwork.ChainID, to)
|
||||
return h.packL2AmmWrapperTx(abi, params.ToChain.ChainID, params.ToAddr)
|
||||
case hop.CctpL2Bridge:
|
||||
return h.packCctpL2BridgeTx(abi, toNetwork.ChainID, to)
|
||||
return h.packCctpL2BridgeTx(abi, params.ToChain.ChainID, params.ToAddr)
|
||||
case hop.L2Bridge:
|
||||
return h.packL2BridgeTx(abi, toNetwork.ChainID, to)
|
||||
return h.packL2BridgeTx(abi, params.ToChain.ChainID, params.ToAddr)
|
||||
}
|
||||
|
||||
return []byte{}, errors.New("contract type not supported yet")
|
||||
}
|
||||
|
||||
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) EstimateGas(params BridgeParams) (uint64, error) {
|
||||
value := big.NewInt(0)
|
||||
if token.IsNative() {
|
||||
value = amountIn
|
||||
if params.FromToken.IsNative() {
|
||||
value = params.AmountIn
|
||||
}
|
||||
|
||||
contractAddress, contractType, err := hop.GetContractAddress(fromNetwork.ChainID, token.Symbol)
|
||||
contractAddress, contractType, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
input, err := h.PackTxInputData(contractType, fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
input, err := h.PackTxInputData(params, contractType)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
ethClient, err := h.contractMaker.RPCClient.EthClient(fromNetwork.ChainID)
|
||||
ethClient, err := h.contractMaker.RPCClient.EthClient(params.FromChain.ChainID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
msg := ethereum.CallMsg{
|
||||
From: from,
|
||||
From: params.FromAddr,
|
||||
To: &contractAddress,
|
||||
Value: value,
|
||||
Data: input,
|
||||
|
@ -216,7 +215,7 @@ func (h *HopBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.N
|
|||
|
||||
estimation, err := ethClient.EstimateGas(context.Background(), msg)
|
||||
if err != nil {
|
||||
if !token.IsNative() {
|
||||
if !params.FromToken.IsNative() {
|
||||
// TODO: this is a temporary solution until we find a better way to estimate the gas
|
||||
// hardcoding the estimation for other than ETH, cause we cannot get a proper estimation without having an approval placed first
|
||||
// this is an error we're facing otherwise: `execution reverted: ERC20: transfer amount exceeds allowance`
|
||||
|
@ -230,42 +229,42 @@ func (h *HopBridge) EstimateGas(fromNetwork *params.Network, toNetwork *params.N
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (h *HopBridge) BuildTx(fromNetwork, toNetwork *params.Network, fromAddress common.Address, toAddress common.Address, token *token.Token, amountIn *big.Int, bonderFee *big.Int) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(toAddress)
|
||||
func (h *HopBridge) BuildTx(params BridgeParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
sendArgs := &TransactionBridge{
|
||||
HopTx: &HopTxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(fromAddress),
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(amountIn),
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
Symbol: token.Symbol,
|
||||
Recipient: toAddress,
|
||||
Amount: (*hexutil.Big)(amountIn),
|
||||
BonderFee: (*hexutil.Big)(bonderFee),
|
||||
ChainID: toNetwork.ChainID,
|
||||
Symbol: params.FromToken.Symbol,
|
||||
Recipient: params.ToAddr,
|
||||
Amount: (*hexutil.Big)(params.AmountIn),
|
||||
BonderFee: (*hexutil.Big)(params.BonderFee),
|
||||
ChainID: params.ToChain.ChainID,
|
||||
},
|
||||
ChainID: fromNetwork.ChainID,
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return h.BuildTransaction(sendArgs)
|
||||
}
|
||||
|
||||
func (h *HopBridge) GetContractAddress(network *params.Network, token *token.Token) (common.Address, error) {
|
||||
address, _, err := hop.GetContractAddress(network.ChainID, token.Symbol)
|
||||
func (h *HopBridge) GetContractAddress(params BridgeParams) (common.Address, error) {
|
||||
address, _, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol)
|
||||
return address, err
|
||||
}
|
||||
|
||||
func (h *HopBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
|
||||
fromNetwork := h.contractMaker.RPCClient.NetworkManager.Find(sendArgs.ChainID)
|
||||
if fromNetwork == nil {
|
||||
fromChain := h.contractMaker.RPCClient.NetworkManager.Find(sendArgs.ChainID)
|
||||
if fromChain == nil {
|
||||
return tx, fmt.Errorf("ChainID not supported %d", sendArgs.ChainID)
|
||||
}
|
||||
|
||||
token := h.tokenManager.FindToken(fromNetwork, sendArgs.HopTx.Symbol)
|
||||
token := h.tokenManager.FindToken(fromChain, sendArgs.HopTx.Symbol)
|
||||
|
||||
nonce, err := h.transactor.NextNonce(h.contractMaker.RPCClient, fromNetwork.ChainID, sendArgs.HopTx.From)
|
||||
nonce, err := h.transactor.NextNonce(h.contractMaker.RPCClient, fromChain.ChainID, sendArgs.HopTx.From)
|
||||
if err != nil {
|
||||
return tx, err
|
||||
}
|
||||
|
@ -278,12 +277,12 @@ func (h *HopBridge) sendOrBuild(sendArgs *TransactionBridge, signerFn bind.Signe
|
|||
txOpts.Value = (*big.Int)(sendArgs.HopTx.Amount)
|
||||
}
|
||||
|
||||
ethClient, err := h.contractMaker.RPCClient.EthClient(fromNetwork.ChainID)
|
||||
ethClient, err := h.contractMaker.RPCClient.EthClient(fromChain.ChainID)
|
||||
if err != nil {
|
||||
return tx, err
|
||||
}
|
||||
|
||||
contractAddress, contractType, err := hop.GetContractAddress(fromNetwork.ChainID, sendArgs.HopTx.Symbol)
|
||||
contractAddress, contractType, err := hop.GetContractAddress(fromChain.ChainID, sendArgs.HopTx.Symbol)
|
||||
if err != nil {
|
||||
return tx, err
|
||||
}
|
||||
|
@ -316,32 +315,32 @@ func (h *HopBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethTypes.Tra
|
|||
return h.sendOrBuild(sendArgs, nil)
|
||||
}
|
||||
|
||||
func (h *HopBridge) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) {
|
||||
func (h *HopBridge) CalculateFees(params BridgeParams) (*big.Int, *big.Int, error) {
|
||||
hopChainsMap := map[uint64]string{
|
||||
walletCommon.EthereumMainnet: "ethereum",
|
||||
walletCommon.OptimismMainnet: "optimism",
|
||||
walletCommon.ArbitrumMainnet: "arbitrum",
|
||||
}
|
||||
|
||||
fromChainName, ok := hopChainsMap[from.ChainID]
|
||||
fromChainName, ok := hopChainsMap[params.FromChain.ChainID]
|
||||
if !ok {
|
||||
return nil, nil, errors.New("from chain not supported")
|
||||
}
|
||||
|
||||
toChainName, ok := hopChainsMap[to.ChainID]
|
||||
toChainName, ok := hopChainsMap[params.ToChain.ChainID]
|
||||
if !ok {
|
||||
return nil, nil, errors.New("to chain not supported")
|
||||
}
|
||||
|
||||
params := netUrl.Values{}
|
||||
params.Add("amount", amountIn.String())
|
||||
params.Add("token", token.Symbol)
|
||||
params.Add("fromChain", fromChainName)
|
||||
params.Add("toChain", toChainName)
|
||||
params.Add("slippage", "0.5") // menas 0.5%
|
||||
reqParams := netUrl.Values{}
|
||||
reqParams.Add("amount", params.AmountIn.String())
|
||||
reqParams.Add("token", params.FromToken.Symbol)
|
||||
reqParams.Add("fromChain", fromChainName)
|
||||
reqParams.Add("toChain", toChainName)
|
||||
reqParams.Add("slippage", "0.5") // menas 0.5%
|
||||
|
||||
url := "https://api.hop.exchange/v1/quote"
|
||||
response, err := h.httpClient.DoGetRequest(context.Background(), url, params)
|
||||
response, err := h.httpClient.DoGetRequest(context.Background(), url, reqParams)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -360,7 +359,7 @@ func (h *HopBridge) CalculateFees(from, to *params.Network, token *token.Token,
|
|||
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(params BridgeParams) (*big.Int, error) {
|
||||
return h.bonderFee.EstimatedRecieved.Int, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,7 @@ import (
|
|||
gomock "github.com/golang/mock/gomock"
|
||||
account "github.com/status-im/status-go/account"
|
||||
types0 "github.com/status-im/status-go/eth-node/types"
|
||||
params "github.com/status-im/status-go/params"
|
||||
bridge "github.com/status-im/status-go/services/wallet/bridge"
|
||||
token "github.com/status-im/status-go/services/wallet/token"
|
||||
)
|
||||
|
||||
// MockBridge is a mock of Bridge interface.
|
||||
|
@ -42,18 +40,18 @@ func (m *MockBridge) EXPECT() *MockBridgeMockRecorder {
|
|||
}
|
||||
|
||||
// AvailableFor mocks base method.
|
||||
func (m *MockBridge) AvailableFor(from, to *params.Network, token, toToken *token.Token) (bool, error) {
|
||||
func (m *MockBridge) AvailableFor(params bridge.BridgeParams) (bool, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "AvailableFor", from, to, token, toToken)
|
||||
ret := m.ctrl.Call(m, "AvailableFor", params)
|
||||
ret0, _ := ret[0].(bool)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// AvailableFor indicates an expected call of AvailableFor.
|
||||
func (mr *MockBridgeMockRecorder) AvailableFor(from, to, token, toToken interface{}) *gomock.Call {
|
||||
func (mr *MockBridgeMockRecorder) AvailableFor(params interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AvailableFor", reflect.TypeOf((*MockBridge)(nil).AvailableFor), from, to, token, toToken)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AvailableFor", reflect.TypeOf((*MockBridge)(nil).AvailableFor), params)
|
||||
}
|
||||
|
||||
// BuildTransaction mocks base method.
|
||||
|
@ -72,39 +70,39 @@ func (mr *MockBridgeMockRecorder) BuildTransaction(sendArgs interface{}) *gomock
|
|||
}
|
||||
|
||||
// BuildTx mocks base method.
|
||||
func (m *MockBridge) BuildTx(fromNetwork, toNetwork *params.Network, fromAddress, toAddress common.Address, token *token.Token, amountIn, bonderFee *big.Int) (*types.Transaction, error) {
|
||||
func (m *MockBridge) BuildTx(params bridge.BridgeParams) (*types.Transaction, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "BuildTx", fromNetwork, toNetwork, fromAddress, toAddress, token, amountIn, bonderFee)
|
||||
ret := m.ctrl.Call(m, "BuildTx", params)
|
||||
ret0, _ := ret[0].(*types.Transaction)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// BuildTx indicates an expected call of BuildTx.
|
||||
func (mr *MockBridgeMockRecorder) BuildTx(fromNetwork, toNetwork, fromAddress, toAddress, token, amountIn, bonderFee interface{}) *gomock.Call {
|
||||
func (mr *MockBridgeMockRecorder) BuildTx(params interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTx", reflect.TypeOf((*MockBridge)(nil).BuildTx), fromNetwork, toNetwork, fromAddress, toAddress, token, amountIn, bonderFee)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildTx", reflect.TypeOf((*MockBridge)(nil).BuildTx), params)
|
||||
}
|
||||
|
||||
// CalculateAmountOut mocks base method.
|
||||
func (m *MockBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
||||
func (m *MockBridge) CalculateAmountOut(params bridge.BridgeParams) (*big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CalculateAmountOut", from, to, amountIn, symbol)
|
||||
ret := m.ctrl.Call(m, "CalculateAmountOut", params)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// CalculateAmountOut indicates an expected call of CalculateAmountOut.
|
||||
func (mr *MockBridgeMockRecorder) CalculateAmountOut(from, to, amountIn, symbol interface{}) *gomock.Call {
|
||||
func (mr *MockBridgeMockRecorder) CalculateAmountOut(params interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateAmountOut", reflect.TypeOf((*MockBridge)(nil).CalculateAmountOut), from, to, amountIn, symbol)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateAmountOut", reflect.TypeOf((*MockBridge)(nil).CalculateAmountOut), params)
|
||||
}
|
||||
|
||||
// CalculateFees mocks base method.
|
||||
func (m *MockBridge) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) {
|
||||
func (m *MockBridge) CalculateFees(params bridge.BridgeParams) (*big.Int, *big.Int, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "CalculateFees", from, to, token, amountIn)
|
||||
ret := m.ctrl.Call(m, "CalculateFees", params)
|
||||
ret0, _ := ret[0].(*big.Int)
|
||||
ret1, _ := ret[1].(*big.Int)
|
||||
ret2, _ := ret[2].(error)
|
||||
|
@ -112,39 +110,39 @@ func (m *MockBridge) CalculateFees(from, to *params.Network, token *token.Token,
|
|||
}
|
||||
|
||||
// CalculateFees indicates an expected call of CalculateFees.
|
||||
func (mr *MockBridgeMockRecorder) CalculateFees(from, to, token, amountIn interface{}) *gomock.Call {
|
||||
func (mr *MockBridgeMockRecorder) CalculateFees(params interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateFees", reflect.TypeOf((*MockBridge)(nil).CalculateFees), from, to, token, amountIn)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CalculateFees", reflect.TypeOf((*MockBridge)(nil).CalculateFees), params)
|
||||
}
|
||||
|
||||
// EstimateGas mocks base method.
|
||||
func (m *MockBridge) EstimateGas(fromNetwork, toNetwork *params.Network, from, to common.Address, token, toToken *token.Token, amountIn *big.Int) (uint64, error) {
|
||||
func (m *MockBridge) EstimateGas(params bridge.BridgeParams) (uint64, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "EstimateGas", fromNetwork, toNetwork, from, to, token, toToken, amountIn)
|
||||
ret := m.ctrl.Call(m, "EstimateGas", params)
|
||||
ret0, _ := ret[0].(uint64)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// EstimateGas indicates an expected call of EstimateGas.
|
||||
func (mr *MockBridgeMockRecorder) EstimateGas(fromNetwork, toNetwork, from, to, token, toToken, amountIn interface{}) *gomock.Call {
|
||||
func (mr *MockBridgeMockRecorder) EstimateGas(params interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateGas", reflect.TypeOf((*MockBridge)(nil).EstimateGas), fromNetwork, toNetwork, from, to, token, toToken, amountIn)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateGas", reflect.TypeOf((*MockBridge)(nil).EstimateGas), params)
|
||||
}
|
||||
|
||||
// GetContractAddress mocks base method.
|
||||
func (m *MockBridge) GetContractAddress(network *params.Network, token *token.Token) (common.Address, error) {
|
||||
func (m *MockBridge) GetContractAddress(params bridge.BridgeParams) (common.Address, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetContractAddress", network, token)
|
||||
ret := m.ctrl.Call(m, "GetContractAddress", params)
|
||||
ret0, _ := ret[0].(common.Address)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetContractAddress indicates an expected call of GetContractAddress.
|
||||
func (mr *MockBridgeMockRecorder) GetContractAddress(network, token interface{}) *gomock.Call {
|
||||
func (mr *MockBridgeMockRecorder) GetContractAddress(params interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContractAddress", reflect.TypeOf((*MockBridge)(nil).GetContractAddress), network, token)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContractAddress", reflect.TypeOf((*MockBridge)(nil).GetContractAddress), params)
|
||||
}
|
||||
|
||||
// Name mocks base method.
|
||||
|
@ -162,18 +160,18 @@ func (mr *MockBridgeMockRecorder) Name() *gomock.Call {
|
|||
}
|
||||
|
||||
// PackTxInputData mocks base method.
|
||||
func (m *MockBridge) PackTxInputData(contractType string, fromNetwork, toNetwork *params.Network, from, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
|
||||
func (m *MockBridge) PackTxInputData(params bridge.BridgeParams, contractType string) ([]byte, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "PackTxInputData", contractType, fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
ret := m.ctrl.Call(m, "PackTxInputData", params, contractType)
|
||||
ret0, _ := ret[0].([]byte)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// PackTxInputData indicates an expected call of PackTxInputData.
|
||||
func (mr *MockBridgeMockRecorder) PackTxInputData(contractType, fromNetwork, toNetwork, from, to, token, amountIn interface{}) *gomock.Call {
|
||||
func (mr *MockBridgeMockRecorder) PackTxInputData(params, contractType interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackTxInputData", reflect.TypeOf((*MockBridge)(nil).PackTxInputData), contractType, fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PackTxInputData", reflect.TypeOf((*MockBridge)(nil).PackTxInputData), params, contractType)
|
||||
}
|
||||
|
||||
// Send mocks base method.
|
||||
|
|
|
@ -11,11 +11,9 @@ import (
|
|||
ethTypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||
"github.com/status-im/status-go/services/wallet/thirdparty/paraswap"
|
||||
"github.com/status-im/status-go/services/wallet/token"
|
||||
walletToken "github.com/status-im/status-go/services/wallet/token"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
)
|
||||
|
@ -39,22 +37,22 @@ func NewSwapParaswap(rpcClient *rpc.Client, transactor transactions.TransactorIf
|
|||
}
|
||||
|
||||
func (s *SwapParaswap) Name() string {
|
||||
return "Paraswap"
|
||||
return SwapParaswapName
|
||||
}
|
||||
|
||||
func (s *SwapParaswap) AvailableFor(from, to *params.Network, token *walletToken.Token, toToken *walletToken.Token) (bool, error) {
|
||||
if token == nil || toToken == nil {
|
||||
func (s *SwapParaswap) AvailableFor(params BridgeParams) (bool, error) {
|
||||
if params.FromToken == nil || params.ToToken == nil {
|
||||
return false, errors.New("token and toToken cannot be nil")
|
||||
}
|
||||
|
||||
if from.ChainID != to.ChainID {
|
||||
if params.FromChain.ChainID != params.ToChain.ChainID {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
s.paraswapClient.SetChainID(from.ChainID)
|
||||
s.paraswapClient.SetChainID(params.FromChain.ChainID)
|
||||
|
||||
searchForToken := token.Address == ZeroAddress
|
||||
searchForToToken := toToken.Address == ZeroAddress
|
||||
searchForToken := params.FromToken.Address == ZeroAddress
|
||||
searchForToToken := params.ToToken.Address == ZeroAddress
|
||||
if searchForToToken || searchForToken {
|
||||
tokensList, err := s.paraswapClient.FetchTokensList(context.Background())
|
||||
if err != nil {
|
||||
|
@ -62,17 +60,17 @@ func (s *SwapParaswap) AvailableFor(from, to *params.Network, token *walletToken
|
|||
}
|
||||
|
||||
for _, t := range tokensList {
|
||||
if searchForToken && t.Symbol == token.Symbol {
|
||||
token.Address = common.HexToAddress(t.Address)
|
||||
token.Decimals = t.Decimals
|
||||
if searchForToken && t.Symbol == params.FromToken.Symbol {
|
||||
params.FromToken.Address = common.HexToAddress(t.Address)
|
||||
params.FromToken.Decimals = t.Decimals
|
||||
if !searchForToToken {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if searchForToToken && t.Symbol == toToken.Symbol {
|
||||
toToken.Address = common.HexToAddress(t.Address)
|
||||
toToken.Decimals = t.Decimals
|
||||
if searchForToToken && t.Symbol == params.ToToken.Symbol {
|
||||
params.ToToken.Address = common.HexToAddress(t.Address)
|
||||
params.ToToken.Decimals = t.Decimals
|
||||
if !searchForToken {
|
||||
break
|
||||
}
|
||||
|
@ -80,24 +78,25 @@ func (s *SwapParaswap) AvailableFor(from, to *params.Network, token *walletToken
|
|||
}
|
||||
}
|
||||
|
||||
if token.Address == ZeroAddress || toToken.Address == ZeroAddress {
|
||||
if params.FromToken.Address == ZeroAddress || params.ToToken.Address == ZeroAddress {
|
||||
return false, errors.New("cannot resolve token/s")
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (s *SwapParaswap) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) {
|
||||
func (s *SwapParaswap) CalculateFees(params BridgeParams) (*big.Int, *big.Int, error) {
|
||||
return big.NewInt(0), big.NewInt(0), nil
|
||||
}
|
||||
|
||||
func (s *SwapParaswap) PackTxInputData(contractType string, fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
|
||||
func (s *SwapParaswap) PackTxInputData(params BridgeParams, contractType string) ([]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) {
|
||||
priceRoute, err := s.paraswapClient.FetchPriceRoute(context.Background(), token.Address, token.Decimals, toToken.Address, toToken.Decimals, amountIn, from, to)
|
||||
func (s *SwapParaswap) EstimateGas(params BridgeParams) (uint64, error) {
|
||||
priceRoute, err := s.paraswapClient.FetchPriceRoute(context.Background(), params.FromToken.Address, params.FromToken.Decimals,
|
||||
params.ToToken.Address, params.ToToken.Decimals, params.AmountIn, params.FromAddr, params.ToAddr)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -107,12 +106,12 @@ func (s *SwapParaswap) EstimateGas(fromNetwork *params.Network, toNetwork *param
|
|||
return priceRoute.GasCost.Uint64(), nil
|
||||
}
|
||||
|
||||
func (s *SwapParaswap) GetContractAddress(network *params.Network, token *token.Token) (address common.Address, err error) {
|
||||
if network.ChainID == walletCommon.EthereumMainnet {
|
||||
func (s *SwapParaswap) GetContractAddress(params BridgeParams) (address common.Address, err error) {
|
||||
if params.FromChain.ChainID == walletCommon.EthereumMainnet {
|
||||
address = common.HexToAddress("0x216b4b4ba9f3e719726886d34a177484278bfcae")
|
||||
} else if network.ChainID == walletCommon.ArbitrumMainnet {
|
||||
} else if params.FromChain.ChainID == walletCommon.ArbitrumMainnet {
|
||||
address = common.HexToAddress("0x216b4b4ba9f3e719726886d34a177484278bfcae")
|
||||
} else if network.ChainID == walletCommon.OptimismMainnet {
|
||||
} else if params.FromChain.ChainID == walletCommon.OptimismMainnet {
|
||||
address = common.HexToAddress("0x216b4b4ba9f3e719726886d34a177484278bfcae")
|
||||
} else {
|
||||
err = errors.New("unsupported network")
|
||||
|
@ -120,18 +119,18 @@ func (s *SwapParaswap) GetContractAddress(network *params.Network, token *token.
|
|||
return
|
||||
}
|
||||
|
||||
func (s *SwapParaswap) BuildTx(network, _ *params.Network, fromAddress common.Address, toAddress common.Address, token *token.Token, amountIn *big.Int, _ *big.Int) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(toAddress)
|
||||
func (s *SwapParaswap) BuildTx(params BridgeParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
sendArgs := &TransactionBridge{
|
||||
SwapTx: &SwapTxArgs{
|
||||
SendTxArgs: transactions.SendTxArgs{
|
||||
From: types.Address(fromAddress),
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(amountIn),
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
Symbol: token.Symbol,
|
||||
Symbol: params.FromToken.Symbol,
|
||||
},
|
||||
ChainID: network.ChainID,
|
||||
ChainID: params.FromChain.ChainID,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -202,6 +201,6 @@ func (s *SwapParaswap) Send(sendArgs *TransactionBridge, verifiedAccount *accoun
|
|||
return s.transactor.SendTransactionWithChainID(txBridgeArgs.ChainID, txBridgeArgs.SwapTx.SendTxArgs, verifiedAccount)
|
||||
}
|
||||
|
||||
func (s *SwapParaswap) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
||||
func (s *SwapParaswap) CalculateAmountOut(params BridgeParams) (*big.Int, error) {
|
||||
return s.priceRoute.DestAmount.Int, nil
|
||||
}
|
||||
|
|
|
@ -13,9 +13,7 @@ import (
|
|||
"github.com/status-im/status-go/account"
|
||||
"github.com/status-im/status-go/contracts/ierc20"
|
||||
"github.com/status-im/status-go/eth-node/types"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/rpc"
|
||||
"github.com/status-im/status-go/services/wallet/token"
|
||||
"github.com/status-im/status-go/transactions"
|
||||
)
|
||||
|
||||
|
@ -29,19 +27,19 @@ func NewTransferBridge(rpcClient *rpc.Client, transactor transactions.Transactor
|
|||
}
|
||||
|
||||
func (s *TransferBridge) Name() string {
|
||||
return "Transfer"
|
||||
return TransferName
|
||||
}
|
||||
|
||||
func (s *TransferBridge) AvailableFor(from, to *params.Network, token *token.Token, toToken *token.Token) (bool, error) {
|
||||
return from.ChainID == to.ChainID && token != nil && toToken == nil, nil
|
||||
func (s *TransferBridge) AvailableFor(params BridgeParams) (bool, error) {
|
||||
return params.FromChain.ChainID == params.ToChain.ChainID && params.FromToken != nil && params.ToToken == nil, nil
|
||||
}
|
||||
|
||||
func (s *TransferBridge) CalculateFees(from, to *params.Network, token *token.Token, amountIn *big.Int) (*big.Int, *big.Int, error) {
|
||||
func (s *TransferBridge) CalculateFees(params BridgeParams) (*big.Int, *big.Int, error) {
|
||||
return big.NewInt(0), big.NewInt(0), nil
|
||||
}
|
||||
|
||||
func (s *TransferBridge) PackTxInputData(contractType string, fromNetwork *params.Network, toNetwork *params.Network, from common.Address, to common.Address, token *token.Token, amountIn *big.Int) ([]byte, error) {
|
||||
if token.IsNative() {
|
||||
func (s *TransferBridge) PackTxInputData(params BridgeParams, contractType string) ([]byte, error) {
|
||||
if params.FromToken.IsNative() {
|
||||
return []byte("eth_sendRawTransaction"), nil
|
||||
} else {
|
||||
abi, err := abi.JSON(strings.NewReader(ierc20.IERC20ABI))
|
||||
|
@ -49,28 +47,28 @@ func (s *TransferBridge) PackTxInputData(contractType string, fromNetwork *param
|
|||
return []byte{}, err
|
||||
}
|
||||
return abi.Pack("transfer",
|
||||
to,
|
||||
amountIn,
|
||||
params.ToAddr,
|
||||
params.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(params BridgeParams) (uint64, error) {
|
||||
estimation := uint64(0)
|
||||
var err error
|
||||
|
||||
input, err := s.PackTxInputData("", fromNetwork, toNetwork, from, to, token, amountIn)
|
||||
input, err := s.PackTxInputData(params, "")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if token.IsNative() {
|
||||
estimation, err = s.transactor.EstimateGas(fromNetwork, from, to, amountIn, input)
|
||||
if params.FromToken.IsNative() {
|
||||
estimation, err = s.transactor.EstimateGas(params.FromChain, params.FromAddr, params.ToAddr, params.AmountIn, input)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
} else {
|
||||
ethClient, err := s.rpcClient.EthClient(fromNetwork.ChainID)
|
||||
ethClient, err := s.rpcClient.EthClient(params.FromChain.ChainID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -78,8 +76,8 @@ func (s *TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *par
|
|||
ctx := context.Background()
|
||||
|
||||
msg := ethereum.CallMsg{
|
||||
From: from,
|
||||
To: &token.Address,
|
||||
From: params.FromAddr,
|
||||
To: ¶ms.FromToken.Address,
|
||||
Data: input,
|
||||
}
|
||||
|
||||
|
@ -94,17 +92,17 @@ func (s *TransferBridge) EstimateGas(fromNetwork *params.Network, toNetwork *par
|
|||
return uint64(increasedEstimation), nil
|
||||
}
|
||||
|
||||
func (s *TransferBridge) BuildTx(network, _ *params.Network, fromAddress common.Address, toAddress common.Address, token *token.Token, amountIn *big.Int, bonderFee *big.Int) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(toAddress)
|
||||
if token.IsNative() {
|
||||
func (s *TransferBridge) BuildTx(params BridgeParams) (*ethTypes.Transaction, error) {
|
||||
toAddr := types.Address(params.ToAddr)
|
||||
if params.FromToken.IsNative() {
|
||||
sendArgs := &TransactionBridge{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(fromAddress),
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(amountIn),
|
||||
Value: (*hexutil.Big)(params.AmountIn),
|
||||
Data: types.HexBytes("0x0"),
|
||||
},
|
||||
ChainID: network.ChainID,
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
|
@ -114,20 +112,20 @@ func (s *TransferBridge) BuildTx(network, _ *params.Network, fromAddress common.
|
|||
return nil, err
|
||||
}
|
||||
input, err := abi.Pack("transfer",
|
||||
toAddress,
|
||||
amountIn,
|
||||
params.ToAddr,
|
||||
params.AmountIn,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sendArgs := &TransactionBridge{
|
||||
TransferTx: &transactions.SendTxArgs{
|
||||
From: types.Address(fromAddress),
|
||||
From: types.Address(params.FromAddr),
|
||||
To: &toAddr,
|
||||
Value: (*hexutil.Big)(big.NewInt(0)),
|
||||
Data: input,
|
||||
},
|
||||
ChainID: network.ChainID,
|
||||
ChainID: params.FromChain.ChainID,
|
||||
}
|
||||
|
||||
return s.BuildTransaction(sendArgs)
|
||||
|
@ -141,10 +139,10 @@ func (s *TransferBridge) BuildTransaction(sendArgs *TransactionBridge) (*ethType
|
|||
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, *sendArgs.TransferTx)
|
||||
}
|
||||
|
||||
func (s *TransferBridge) CalculateAmountOut(from, to *params.Network, amountIn *big.Int, symbol string) (*big.Int, error) {
|
||||
return amountIn, nil
|
||||
func (s *TransferBridge) CalculateAmountOut(params BridgeParams) (*big.Int, error) {
|
||||
return params.AmountIn, nil
|
||||
}
|
||||
|
||||
func (s *TransferBridge) GetContractAddress(network *params.Network, token *token.Token) (common.Address, error) {
|
||||
func (s *TransferBridge) GetContractAddress(params BridgeParams) (common.Address, error) {
|
||||
return common.Address{}, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"math/big"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/status-im/status-go/services/wallet/bridge"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -88,7 +89,7 @@ func setupRouteValidationMapsV2(fromLockedAmount map[uint64]*hexutil.Big) (map[u
|
|||
fromExcluded := make(map[uint64]bool)
|
||||
|
||||
for chainID, amount := range fromLockedAmount {
|
||||
if amount.ToInt().Cmp(zero) <= 0 {
|
||||
if amount.ToInt().Cmp(bridge.ZeroBigIntValue) <= 0 {
|
||||
fromExcluded[chainID] = false
|
||||
} else {
|
||||
fromIncluded[chainID] = false
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/services/wallet/bridge"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -83,9 +84,9 @@ func TestSetupRouteValidationMapsV2(t *testing.T) {
|
|||
{
|
||||
name: "Mixed zero and non-zero amounts",
|
||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||
1: (*hexutil.Big)(zero),
|
||||
1: (*hexutil.Big)(bridge.ZeroBigIntValue),
|
||||
2: (*hexutil.Big)(big.NewInt(200)),
|
||||
3: (*hexutil.Big)(zero),
|
||||
3: (*hexutil.Big)(bridge.ZeroBigIntValue),
|
||||
4: (*hexutil.Big)(big.NewInt(400)),
|
||||
},
|
||||
expectedIncluded: map[uint64]bool{
|
||||
|
@ -112,8 +113,8 @@ func TestSetupRouteValidationMapsV2(t *testing.T) {
|
|||
{
|
||||
name: "All zero amounts",
|
||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||
1: (*hexutil.Big)(zero),
|
||||
2: (*hexutil.Big)(zero),
|
||||
1: (*hexutil.Big)(bridge.ZeroBigIntValue),
|
||||
2: (*hexutil.Big)(bridge.ZeroBigIntValue),
|
||||
},
|
||||
expectedIncluded: map[uint64]bool{},
|
||||
expectedExcluded: map[uint64]bool{
|
||||
|
@ -134,7 +135,7 @@ func TestSetupRouteValidationMapsV2(t *testing.T) {
|
|||
{
|
||||
name: "Single zero amount",
|
||||
fromLockedAmount: map[uint64]*hexutil.Big{
|
||||
1: (*hexutil.Big)(zero),
|
||||
1: (*hexutil.Big)(bridge.ZeroBigIntValue),
|
||||
},
|
||||
expectedIncluded: map[uint64]bool{},
|
||||
expectedExcluded: map[uint64]bool{
|
||||
|
|
|
@ -37,12 +37,9 @@ import (
|
|||
// rename and make `router_v2.go` file the main and only file
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// TODO: remove the following two consts once we fully move to routerV2
|
||||
const EstimateUsername = "RandomUsername"
|
||||
const EstimatePubKey = "0x04bb2024ce5d72e45d4a4f8589ae657ef9745855006996115a23a1af88d536cf02c0524a585fce7bfa79d6a9669af735eda6205d6c7e5b3cdc2b8ff7b2fa1f0b56"
|
||||
const ERC721TransferString = "ERC721Transfer"
|
||||
const ERC1155TransferString = "ERC1155Transfer"
|
||||
|
||||
var zero = big.NewInt(0)
|
||||
|
||||
type Path struct {
|
||||
BridgeName string
|
||||
|
@ -151,7 +148,7 @@ func filterRoutes(routes [][]*Path, amountIn *big.Int, fromLockedAmount map[uint
|
|||
fromIncluded := make(map[uint64]bool)
|
||||
fromExcluded := make(map[uint64]bool)
|
||||
for chainID, amount := range fromLockedAmount {
|
||||
if amount.ToInt().Cmp(zero) == 0 {
|
||||
if amount.ToInt().Cmp(bridge.ZeroBigIntValue) == 0 {
|
||||
fromExcluded[chainID] = false
|
||||
} else {
|
||||
fromIncluded[chainID] = false
|
||||
|
@ -262,7 +259,7 @@ func newSuggestedRoutes(
|
|||
rest := new(big.Int).Set(amountIn)
|
||||
for _, path := range best {
|
||||
diff := new(big.Int).Sub(rest, path.MaxAmountIn.ToInt())
|
||||
if diff.Cmp(zero) >= 0 {
|
||||
if diff.Cmp(bridge.ZeroBigIntValue) >= 0 {
|
||||
path.AmountIn = (*hexutil.Big)(path.MaxAmountIn.ToInt())
|
||||
} else {
|
||||
path.AmountIn = (*hexutil.Big)(new(big.Int).Set(rest))
|
||||
|
@ -286,12 +283,15 @@ func NewRouter(rpcClient *rpc.Client, transactor *transactions.Transactor, token
|
|||
cbridge := bridge.NewCbridge(rpcClient, transactor, tokenManager)
|
||||
hop := bridge.NewHopBridge(rpcClient, transactor, tokenManager)
|
||||
paraswap := bridge.NewSwapParaswap(rpcClient, transactor, tokenManager)
|
||||
ensRegister := bridge.NewENSRegisterBridge(rpcClient, transactor, ensService)
|
||||
|
||||
bridges[transfer.Name()] = transfer
|
||||
bridges[erc721Transfer.Name()] = erc721Transfer
|
||||
bridges[hop.Name()] = hop
|
||||
bridges[cbridge.Name()] = cbridge
|
||||
bridges[erc1155Transfer.Name()] = erc1155Transfer
|
||||
bridges[paraswap.Name()] = paraswap
|
||||
bridges[ensRegister.Name()] = ensRegister
|
||||
|
||||
return &Router{
|
||||
rpcClient: rpcClient,
|
||||
|
@ -338,7 +338,7 @@ type Router struct {
|
|||
|
||||
func (r *Router) requireApproval(ctx context.Context, sendType SendType, approvalContractAddress *common.Address, account common.Address, network *params.Network, token *token.Token, amountIn *big.Int) (
|
||||
bool, *big.Int, uint64, uint64, error) {
|
||||
if sendType.IsCollectiblesTransfer() {
|
||||
if sendType.IsCollectiblesTransfer() || sendType.IsEnsTransfer() {
|
||||
return false, nil, 0, 0, nil
|
||||
}
|
||||
|
||||
|
@ -542,8 +542,13 @@ func (r *Router) SuggestedRoutes(
|
|||
maxFees := gasFees.feeFor(gasFeeMode)
|
||||
|
||||
estimatedTime := r.feesManager.TransactionEstimatedTime(ctx, network.ChainID, maxFees)
|
||||
for _, bridge := range r.bridges {
|
||||
if !sendType.canUseBridge(bridge) {
|
||||
for _, brdg := range r.bridges {
|
||||
// Skip bridges that are added because of the Router V2, to not break the current functionality
|
||||
if brdg.Name() == bridge.ENSRegisterName {
|
||||
continue
|
||||
}
|
||||
|
||||
if !sendType.canUseBridge(brdg) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -567,7 +572,17 @@ func (r *Router) SuggestedRoutes(
|
|||
continue
|
||||
}
|
||||
|
||||
can, err := bridge.AvailableFor(network, dest, token, toToken)
|
||||
bridgeParams := bridge.BridgeParams{
|
||||
FromChain: network,
|
||||
ToChain: dest,
|
||||
FromToken: token,
|
||||
ToToken: toToken,
|
||||
ToAddr: addrTo,
|
||||
FromAddr: addrFrom,
|
||||
AmountIn: amountIn,
|
||||
}
|
||||
|
||||
can, err := brdg.AvailableFor(bridgeParams)
|
||||
if err != nil || !can {
|
||||
continue
|
||||
}
|
||||
|
@ -575,11 +590,11 @@ func (r *Router) SuggestedRoutes(
|
|||
continue
|
||||
}
|
||||
|
||||
bonderFees, tokenFees, err := bridge.CalculateFees(network, dest, token, amountIn)
|
||||
bonderFees, tokenFees, err := brdg.CalculateFees(bridgeParams)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if bonderFees.Cmp(zero) != 0 {
|
||||
if bonderFees.Cmp(bridge.ZeroBigIntValue) != 0 {
|
||||
if maxAmountIn.ToInt().Cmp(amountIn) >= 0 {
|
||||
if bonderFees.Cmp(amountIn) >= 0 {
|
||||
continue
|
||||
|
@ -592,7 +607,7 @@ func (r *Router) SuggestedRoutes(
|
|||
}
|
||||
gasLimit := uint64(0)
|
||||
if sendType.isTransfer(false) {
|
||||
gasLimit, err = bridge.EstimateGas(network, dest, addrFrom, addrTo, token, toToken, amountIn)
|
||||
gasLimit, err = brdg.EstimateGas(bridgeParams)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -600,7 +615,7 @@ func (r *Router) SuggestedRoutes(
|
|||
gasLimit = sendType.EstimateGas(r.ensService, r.stickersService, network, addrFrom, tokenID)
|
||||
}
|
||||
|
||||
approvalContractAddress, err := bridge.GetContractAddress(network, token)
|
||||
approvalContractAddress, err := brdg.GetContractAddress(bridgeParams)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -611,7 +626,7 @@ func (r *Router) SuggestedRoutes(
|
|||
|
||||
var l1GasFeeWei uint64
|
||||
if sendType.needL1Fee() {
|
||||
txInputData, err := bridge.PackTxInputData("", network, dest, addrFrom, addrTo, token, amountIn)
|
||||
txInputData, err := brdg.PackTxInputData(bridgeParams, "")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -661,12 +676,12 @@ func (r *Router) SuggestedRoutes(
|
|||
cost.Add(cost, l1GasCost)
|
||||
mu.Lock()
|
||||
candidates = append(candidates, &Path{
|
||||
BridgeName: bridge.Name(),
|
||||
BridgeName: brdg.Name(),
|
||||
From: network,
|
||||
To: dest,
|
||||
MaxAmountIn: maxAmountIn,
|
||||
AmountIn: (*hexutil.Big)(zero),
|
||||
AmountOut: (*hexutil.Big)(zero),
|
||||
AmountIn: (*hexutil.Big)(bridge.ZeroBigIntValue),
|
||||
AmountOut: (*hexutil.Big)(bridge.ZeroBigIntValue),
|
||||
GasAmount: gasLimit,
|
||||
GasFees: gasFees,
|
||||
BonderFees: (*hexutil.Big)(bonderFees),
|
||||
|
@ -691,7 +706,16 @@ func (r *Router) SuggestedRoutes(
|
|||
suggestedRoutes.TokenPrice = prices[tokenID]
|
||||
suggestedRoutes.NativeChainTokenPrice = prices["ETH"]
|
||||
for _, path := range suggestedRoutes.Best {
|
||||
amountOut, err := r.bridges[path.BridgeName].CalculateAmountOut(path.From, path.To, (*big.Int)(path.AmountIn), tokenID)
|
||||
bridgeParams := bridge.BridgeParams{
|
||||
FromChain: path.From,
|
||||
ToChain: path.To,
|
||||
AmountIn: path.AmountIn.ToInt(),
|
||||
FromToken: &token.Token{
|
||||
Symbol: tokenID,
|
||||
},
|
||||
}
|
||||
|
||||
amountOut, err := r.bridges[path.BridgeName].CalculateAmountOut(bridgeParams)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ func (s SendType) IsCollectiblesTransfer() bool {
|
|||
return s == ERC721Transfer || s == ERC1155Transfer
|
||||
}
|
||||
|
||||
func (s SendType) IsEnsTransfer() bool {
|
||||
return s == ENSRegister || s == ENSRelease || s == ENSSetPubKey
|
||||
}
|
||||
|
||||
func (s SendType) FetchPrices(marketManager *market.Manager, tokenID string) (map[string]float64, error) {
|
||||
symbols := []string{tokenID, "ETH"}
|
||||
if s.IsCollectiblesTransfer() {
|
||||
|
@ -83,6 +87,7 @@ func (s SendType) FindToken(tokenManager *token.Manager, collectibles *collectib
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: remove this function once we fully move to routerV2
|
||||
func (s SendType) isTransfer(routerV2Logic bool) bool {
|
||||
return s == Transfer ||
|
||||
s == Bridge && routerV2Logic ||
|
||||
|
@ -98,16 +103,18 @@ func (s SendType) canUseBridge(b bridge.Bridge) bool {
|
|||
bridgeName := b.Name()
|
||||
switch s {
|
||||
case ERC721Transfer:
|
||||
return bridgeName == ERC721TransferString
|
||||
return bridgeName == bridge.ERC721TransferName
|
||||
case ERC1155Transfer:
|
||||
return bridgeName == ERC1155TransferString
|
||||
return bridgeName == bridge.ERC1155TransferName
|
||||
case ENSRegister:
|
||||
return bridgeName == bridge.ENSRegisterName
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
func (s SendType) isAvailableBetween(from, to *params.Network) bool {
|
||||
if s.IsCollectiblesTransfer() {
|
||||
if s.IsCollectiblesTransfer() || s.IsEnsTransfer() {
|
||||
return from.ChainID == to.ChainID
|
||||
}
|
||||
|
||||
|
@ -142,6 +149,10 @@ func (s SendType) isAvailableFor(network *params.Network) bool {
|
|||
return swapAllowedNetworks[network.ChainID]
|
||||
}
|
||||
|
||||
if s.IsEnsTransfer() {
|
||||
return network.ChainID == walletCommon.EthereumMainnet || network.ChainID == walletCommon.EthereumSepolia
|
||||
}
|
||||
|
||||
// Check for any SendType available for all networks
|
||||
if s == Transfer || s == Bridge || s.IsCollectiblesTransfer() || allAllowedNetworks[network.ChainID] {
|
||||
return true
|
||||
|
@ -150,10 +161,11 @@ func (s SendType) isAvailableFor(network *params.Network) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// TODO: remove this function once we fully move to routerV2
|
||||
func (s SendType) EstimateGas(ensService *ens.Service, stickersService *stickers.Service, network *params.Network, from common.Address, tokenID string) uint64 {
|
||||
tx := transactions.SendTxArgs{
|
||||
From: (types.Address)(from),
|
||||
Value: (*hexutil.Big)(zero),
|
||||
Value: (*hexutil.Big)(bridge.ZeroBigIntValue),
|
||||
}
|
||||
switch s {
|
||||
case ENSRegister:
|
||||
|
|
|
@ -12,9 +12,25 @@ import (
|
|||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
"github.com/status-im/status-go/params"
|
||||
"github.com/status-im/status-go/services/wallet/async"
|
||||
"github.com/status-im/status-go/services/wallet/bridge"
|
||||
walletCommon "github.com/status-im/status-go/services/wallet/common"
|
||||
walletToken "github.com/status-im/status-go/services/wallet/token"
|
||||
)
|
||||
|
||||
var (
|
||||
supportedNetworks = map[uint64]bool{
|
||||
walletCommon.EthereumMainnet: true,
|
||||
walletCommon.OptimismMainnet: true,
|
||||
walletCommon.ArbitrumMainnet: true,
|
||||
}
|
||||
|
||||
supportedTestNetworks = map[uint64]bool{
|
||||
walletCommon.EthereumSepolia: true,
|
||||
walletCommon.OptimismSepolia: true,
|
||||
walletCommon.ArbitrumSepolia: true,
|
||||
}
|
||||
)
|
||||
|
||||
type RouteInputParams struct {
|
||||
SendType SendType `json:"sendType" validate:"required"`
|
||||
AddrFrom common.Address `json:"addrFrom" validate:"required"`
|
||||
|
@ -28,6 +44,10 @@ type RouteInputParams struct {
|
|||
GasFeeMode GasFeeMode `json:"gasFeeMode" validate:"required"`
|
||||
FromLockedAmount map[uint64]*hexutil.Big `json:"fromLockedAmount"`
|
||||
TestnetMode bool `json:"testnetMode"`
|
||||
|
||||
// For send types like EnsRegister, EnsRelease, EnsSetPubKey, StickersBuy
|
||||
Username string `json:"username"`
|
||||
PublicKey string `json:"publicKey"`
|
||||
}
|
||||
|
||||
type PathV2 struct {
|
||||
|
@ -112,7 +132,7 @@ func newSuggestedRoutesV2(
|
|||
rest := new(big.Int).Set(amountIn)
|
||||
for _, path := range best {
|
||||
diff := new(big.Int).Sub(rest, path.AmountIn.ToInt())
|
||||
if diff.Cmp(zero) >= 0 {
|
||||
if diff.Cmp(bridge.ZeroBigIntValue) >= 0 {
|
||||
path.AmountIn = (*hexutil.Big)(path.AmountIn.ToInt())
|
||||
} else {
|
||||
path.AmountIn = (*hexutil.Big)(new(big.Int).Set(rest))
|
||||
|
@ -214,7 +234,7 @@ func findBestV2(routes [][]*PathV2, tokenPrice float64, nativeChainTokenPrice fl
|
|||
pathCost = new(big.Float).Mul(txFeeInEth, nativeTokenPrice)
|
||||
}
|
||||
|
||||
if path.TxBonderFees != nil && path.TxBonderFees.ToInt().Cmp(zero) > 0 {
|
||||
if path.TxBonderFees != nil && path.TxBonderFees.ToInt().Cmp(bridge.ZeroBigIntValue) > 0 {
|
||||
path.requiredTokenBalance.Add(path.requiredTokenBalance, path.TxBonderFees.ToInt())
|
||||
pathCost.Add(pathCost, new(big.Float).Mul(
|
||||
new(big.Float).Quo(new(big.Float).SetInt(path.TxBonderFees.ToInt()), tokenDenominator),
|
||||
|
@ -222,7 +242,7 @@ func findBestV2(routes [][]*PathV2, tokenPrice float64, nativeChainTokenPrice fl
|
|||
|
||||
}
|
||||
|
||||
if path.TxL1Fee != nil && path.TxL1Fee.ToInt().Cmp(zero) > 0 {
|
||||
if path.TxL1Fee != nil && path.TxL1Fee.ToInt().Cmp(bridge.ZeroBigIntValue) > 0 {
|
||||
l1FeeInWei := path.TxL1Fee.ToInt()
|
||||
l1FeeInEth := gweiToEth(weiToGwei(l1FeeInWei))
|
||||
|
||||
|
@ -230,7 +250,7 @@ func findBestV2(routes [][]*PathV2, tokenPrice float64, nativeChainTokenPrice fl
|
|||
pathCost.Add(pathCost, new(big.Float).Mul(l1FeeInEth, nativeTokenPrice))
|
||||
}
|
||||
|
||||
if path.TxTokenFees != nil && path.TxTokenFees.ToInt().Cmp(zero) > 0 && path.FromToken != nil {
|
||||
if path.TxTokenFees != nil && path.TxTokenFees.ToInt().Cmp(bridge.ZeroBigIntValue) > 0 && path.FromToken != nil {
|
||||
path.requiredTokenBalance.Add(path.requiredTokenBalance, path.TxTokenFees.ToInt())
|
||||
pathCost.Add(pathCost, new(big.Float).Mul(
|
||||
new(big.Float).Quo(new(big.Float).SetInt(path.TxTokenFees.ToInt()), tokenDenominator),
|
||||
|
@ -268,7 +288,50 @@ func findBestV2(routes [][]*PathV2, tokenPrice float64, nativeChainTokenPrice fl
|
|||
return best
|
||||
}
|
||||
|
||||
func validateInputData(input *RouteInputParams) error {
|
||||
if input.SendType == ENSRegister {
|
||||
if input.Username == "" || input.PublicKey == "" {
|
||||
return errors.New("username and public key are required for ENSRegister")
|
||||
}
|
||||
if input.TestnetMode {
|
||||
if input.TokenID != bridge.SttSymbol {
|
||||
return errors.New("only STT is supported for ENSRegister on testnet")
|
||||
}
|
||||
} else {
|
||||
if input.TokenID != bridge.SntSymbol {
|
||||
return errors.New("only SNT is supported for ENSRegister")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if input.FromLockedAmount != nil && len(input.FromLockedAmount) > 0 {
|
||||
for chainID, amount := range input.FromLockedAmount {
|
||||
if input.TestnetMode {
|
||||
if !supportedTestNetworks[chainID] {
|
||||
return errors.New("locked amount is not supported for the selected network")
|
||||
}
|
||||
} else {
|
||||
if !supportedNetworks[chainID] {
|
||||
return errors.New("locked amount is not supported for the selected network")
|
||||
}
|
||||
}
|
||||
|
||||
if amount == nil || amount.ToInt().Sign() < 0 {
|
||||
return errors.New("locked amount must be positive")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams) (*SuggestedRoutesV2, error) {
|
||||
err := validateInputData(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
networks, err := r.rpcClient.NetworkManager.Get(false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -294,12 +357,16 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
|
|||
continue
|
||||
}
|
||||
|
||||
token := input.SendType.FindToken(r.tokenManager, r.collectiblesService, input.AddrFrom, network, input.TokenID)
|
||||
var (
|
||||
token *walletToken.Token
|
||||
toToken *walletToken.Token
|
||||
)
|
||||
|
||||
token = input.SendType.FindToken(r.tokenManager, r.collectiblesService, input.AddrFrom, network, input.TokenID)
|
||||
if token == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var toToken *walletToken.Token
|
||||
if input.SendType == Swap {
|
||||
toToken = input.SendType.FindToken(r.tokenManager, r.collectiblesService, common.Address{}, network, input.ToTokenID)
|
||||
}
|
||||
|
@ -325,8 +392,8 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
|
|||
return err
|
||||
}
|
||||
|
||||
for _, bridge := range r.bridges {
|
||||
if !input.SendType.canUseBridge(bridge) {
|
||||
for _, brdg := range r.bridges {
|
||||
if !input.SendType.canUseBridge(brdg) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -351,27 +418,35 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
|
|||
continue
|
||||
}
|
||||
|
||||
can, err := bridge.AvailableFor(network, dest, token, toToken)
|
||||
bridgeParams := bridge.BridgeParams{
|
||||
FromChain: network,
|
||||
ToChain: dest,
|
||||
FromToken: token,
|
||||
ToToken: toToken,
|
||||
ToAddr: input.AddrTo,
|
||||
FromAddr: input.AddrFrom,
|
||||
AmountIn: amountToSend,
|
||||
|
||||
Username: input.Username,
|
||||
PublicKey: input.PublicKey,
|
||||
}
|
||||
|
||||
can, err := brdg.AvailableFor(bridgeParams)
|
||||
if err != nil || !can {
|
||||
continue
|
||||
}
|
||||
|
||||
bonderFees, tokenFees, err := bridge.CalculateFees(network, dest, token, amountToSend)
|
||||
bonderFees, tokenFees, err := brdg.CalculateFees(bridgeParams)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
gasLimit := uint64(0)
|
||||
if input.SendType.isTransfer(true) {
|
||||
gasLimit, err = bridge.EstimateGas(network, dest, input.AddrFrom, input.AddrTo, token, toToken, amountToSend)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
gasLimit = input.SendType.EstimateGas(r.ensService, r.stickersService, network, input.AddrFrom, input.TokenID)
|
||||
gasLimit, err := brdg.EstimateGas(bridgeParams)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
approvalContractAddress, err := bridge.GetContractAddress(network, token)
|
||||
approvalContractAddress, err := brdg.GetContractAddress(bridgeParams)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -383,7 +458,7 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
|
|||
var l1FeeWei uint64
|
||||
if input.SendType.needL1Fee() {
|
||||
|
||||
txInputData, err := bridge.PackTxInputData("", network, dest, input.AddrFrom, input.AddrTo, token, amountToSend)
|
||||
txInputData, err := brdg.PackTxInputData(bridgeParams, "")
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -407,7 +482,7 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
|
|||
selctedPriorityFee = priorityFees.Low
|
||||
}
|
||||
|
||||
amountOut, err := bridge.CalculateAmountOut(network, dest, amountToSend, token.Symbol)
|
||||
amountOut, err := brdg.CalculateAmountOut(bridgeParams)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
@ -421,7 +496,7 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
|
|||
|
||||
mu.Lock()
|
||||
candidates = append(candidates, &PathV2{
|
||||
BridgeName: bridge.Name(),
|
||||
BridgeName: brdg.Name(),
|
||||
FromChain: network,
|
||||
ToChain: network,
|
||||
FromToken: token,
|
||||
|
|
Loading…
Reference in New Issue