feat(router)_: return processor error when no routes are found

This commit is contained in:
Dario Gabriel Lipicar 2024-07-18 09:20:54 -03:00 committed by Andrea Maria Piana
parent 54555b47de
commit afc6e7bcb9
17 changed files with 370 additions and 138 deletions

View File

@ -7,6 +7,8 @@ import (
// ErrorCode represents a specific error code.
type ErrorCode string
const GenericErrorCode ErrorCode = "0"
// ErrorResponse represents an error response structure.
type ErrorResponse struct {
Code ErrorCode `json:"code"`
@ -19,6 +21,12 @@ func (e *ErrorResponse) Error() string {
return string(errorJSON)
}
// IsErrorResponse determines if an error is an ErrorResponse.
func IsErrorResponse(err error) bool {
_, ok := err.(*ErrorResponse)
return ok
}
// CreateErrorResponseFromError creates an ErrorResponse from a generic error.
func CreateErrorResponseFromError(err error) error {
if err == nil {
@ -28,7 +36,7 @@ func CreateErrorResponseFromError(err error) error {
return errResp
}
return &ErrorResponse{
Code: "0",
Code: GenericErrorCode,
Details: err.Error(),
}
}

View File

@ -28,4 +28,5 @@ var (
ErrENSSetPubKeyInvalidUsername = &errors.ErrorResponse{Code: errors.ErrorCode("WR-020"), Details: "a valid username, ending in '.eth', is required for ENSSetPubKey"}
ErrLockedAmountExcludesAllSupported = &errors.ErrorResponse{Code: errors.ErrorCode("WR-021"), Details: "all supported chains are excluded, routing impossible"}
ErrTokenNotFound = &errors.ErrorResponse{Code: errors.ErrorCode("WR-022"), Details: "token not found"}
ErrNoBestRouteFound = &errors.ErrorResponse{Code: errors.ErrorCode("WR-023"), Details: "no best route found"}
)

View File

@ -1,6 +1,8 @@
package pathprocessor
import (
"context"
"github.com/status-im/status-go/errors"
)
@ -30,4 +32,66 @@ var (
ErrFromAndToChainsMustBeDifferent = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-022"), Details: "from and to chains must be different"}
ErrFromAndToChainsMustBeSame = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-023"), Details: "from and to chains must be same"}
ErrFromAndToTokensMustBeDifferent = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-024"), Details: "from and to tokens must be different"}
ErrTransferCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-025"), Details: "Transfer custom error"}
ErrERC721TransferCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-026"), Details: "ERC721Transfer custom error"}
ErrERC1155TransferCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-027"), Details: "ERC1155Transfer custom error"}
ErrBridgeHopCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-028"), Details: "Hop custom error"}
ErrBridgeCellerCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-029"), Details: "CBridge custom error"}
ErrSwapParaswapCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-030"), Details: "Paraswap custom error"}
ErrENSRegisterCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-031"), Details: "ENSRegister custom error"}
ErrENSReleaseCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-032"), Details: "ENSRelease custom error"}
ErrENSPublicKeyCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-033"), Details: "ENSPublicKey custom error"}
ErrStickersBuyCustomError = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-034"), Details: "StickersBuy custom error"}
ErrContextCancelled = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-035"), Details: "context cancelled"}
ErrContextDeadlineExceeded = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-036"), Details: "context deadline exceeded"}
ErrPriceTimeout = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-037"), Details: "price timeout"}
ErrNotEnoughLiquidity = &errors.ErrorResponse{Code: errors.ErrorCode("WPP-038"), Details: "not enough liquidity"}
)
func createErrorResponse(processorName string, err error) error {
if err == nil {
return nil
}
genericErrResp := errors.CreateErrorResponseFromError(err).(*errors.ErrorResponse)
if genericErrResp.Code != errors.GenericErrorCode {
return genericErrResp
}
switch genericErrResp.Details {
case context.Canceled.Error():
return ErrContextCancelled
case context.DeadlineExceeded.Error():
return ErrContextDeadlineExceeded
}
var customErrResp *errors.ErrorResponse
switch processorName {
case ProcessorTransferName:
customErrResp = ErrTransferCustomError
case ProcessorERC721Name:
customErrResp = ErrERC721TransferCustomError
case ProcessorERC1155Name:
customErrResp = ErrERC1155TransferCustomError
case ProcessorBridgeHopName:
customErrResp = ErrBridgeHopCustomError
case ProcessorBridgeCelerName:
customErrResp = ErrBridgeCellerCustomError
case ProcessorSwapParaswapName:
customErrResp = ErrSwapParaswapCustomError
case ProcessorENSRegisterName:
customErrResp = ErrENSRegisterCustomError
case ProcessorENSReleaseName:
customErrResp = ErrENSReleaseCustomError
case ProcessorENSPublicKeyName:
customErrResp = ErrENSPublicKeyCustomError
case ProcessorStickersBuyName:
customErrResp = ErrStickersBuyCustomError
default:
return genericErrResp
}
customErrResp.Details = genericErrResp.Details
return customErrResp
}

View File

@ -0,0 +1,70 @@
package pathprocessor
import (
"context"
"errors"
"testing"
s_errors "github.com/status-im/status-go/errors"
"github.com/stretchr/testify/require"
)
func TestPlainError(t *testing.T) {
const errString = "plain error"
err := errors.New(errString)
processorNames := []string{
ProcessorTransferName,
ProcessorTransferName,
ProcessorBridgeHopName,
ProcessorBridgeCelerName,
ProcessorSwapParaswapName,
ProcessorERC721Name,
ProcessorERC1155Name,
ProcessorENSRegisterName,
ProcessorENSReleaseName,
ProcessorENSPublicKeyName,
ProcessorStickersBuyName,
}
for _, processorName := range processorNames {
ppErrResp := createErrorResponse(processorName, err)
castPPErrResp := ppErrResp.(*s_errors.ErrorResponse)
require.NotEqual(t, s_errors.GenericErrorCode, castPPErrResp.Code)
require.Equal(t, errString, castPPErrResp.Details)
}
}
func TestContextErrors(t *testing.T) {
ppErrResp := createErrorResponse("Unknown", context.Canceled)
require.Equal(t, ErrContextCancelled, ppErrResp)
ppErrResp = createErrorResponse("Unknown", context.DeadlineExceeded)
require.Equal(t, ErrContextDeadlineExceeded, ppErrResp)
}
func TestErrorResponse(t *testing.T) {
const errString = "error response"
err := errors.New(errString)
errResp := s_errors.CreateErrorResponseFromError(err)
ppErrResp := createErrorResponse("Unknown", errResp)
castPPErrResp := ppErrResp.(*s_errors.ErrorResponse)
require.Equal(t, s_errors.GenericErrorCode, castPPErrResp.Code)
require.Equal(t, errString, castPPErrResp.Details)
}
func TestNonGenericErrorResponse(t *testing.T) {
errResp := &s_errors.ErrorResponse{
Code: "Not Generic Code",
Details: "Not Generic Error Response",
}
err := s_errors.CreateErrorResponseFromError(errResp)
ppErrResp := createErrorResponse(ProcessorTransferName, err)
castPPErrResp := ppErrResp.(*s_errors.ErrorResponse)
require.Equal(t, errResp.Code, castPPErrResp.Code)
require.Equal(t, errResp.Details, castPPErrResp.Details)
}

View File

@ -22,7 +22,6 @@ import (
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/wallet/router/pathprocessor/cbridge"
"github.com/status-im/status-go/services/wallet/thirdparty"
@ -63,6 +62,10 @@ func NewCelerBridgeProcessor(rpcClient *rpc.Client, transactor transactions.Tran
}
}
func createBridgeCellerErrorResponse(err error) error {
return createErrorResponse(ProcessorBridgeCelerName, err)
}
func (s *CelerBridgeProcessor) Name() string {
return ProcessorBridgeCelerName
}
@ -84,13 +87,13 @@ func (s *CelerBridgeProcessor) estimateAmt(from, to *params.Network, amountIn *b
url := fmt.Sprintf("%s/v2/estimateAmt", base)
response, err := s.httpClient.DoGetRequest(context.Background(), url, params)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
var res cbridge.EstimateAmtResponse
err = json.Unmarshal(response, &res)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
return &res, nil
}
@ -111,13 +114,13 @@ func (s *CelerBridgeProcessor) getTransferConfig(isTest bool) (*cbridge.GetTrans
url := fmt.Sprintf("%s/v2/getTransferConfigs", base)
response, err := s.httpClient.DoGetRequest(context.Background(), url, nil)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
var res cbridge.GetTransferConfigsResponse
err = json.Unmarshal(response, &res)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
if isTest {
s.testTransferConfig = &res
@ -134,10 +137,10 @@ func (s *CelerBridgeProcessor) AvailableFor(params ProcessorInputParams) (bool,
transferConfig, err := s.getTransferConfig(params.FromChain.IsTest)
if err != nil {
return false, statusErrors.CreateErrorResponseFromError(err)
return false, createBridgeCellerErrorResponse(err)
}
if transferConfig.Err != nil {
return false, statusErrors.CreateErrorResponseFromError(errors.New(transferConfig.Err.Msg))
return false, createBridgeCellerErrorResponse(errors.New(transferConfig.Err.Msg))
}
var fromAvailable *cbridge.Chain
@ -189,7 +192,7 @@ func (s *CelerBridgeProcessor) AvailableFor(params ProcessorInputParams) (bool,
func (s *CelerBridgeProcessor) CalculateFees(params ProcessorInputParams) (*big.Int, *big.Int, error) {
amt, err := s.estimateAmt(params.FromChain, params.ToChain, params.AmountIn, params.FromToken.Symbol)
if err != nil {
return nil, nil, statusErrors.CreateErrorResponseFromError(err)
return nil, nil, createBridgeCellerErrorResponse(err)
}
baseFee, ok := new(big.Int).SetString(amt.BaseFee, 10)
if !ok {
@ -206,7 +209,7 @@ func (s *CelerBridgeProcessor) CalculateFees(params ProcessorInputParams) (*big.
func (c *CelerBridgeProcessor) PackTxInputData(params ProcessorInputParams) ([]byte, error) {
abi, err := abi.JSON(strings.NewReader(celer.CelerABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createBridgeCellerErrorResponse(err)
}
if params.FromToken.IsNative() {
@ -243,17 +246,17 @@ func (s *CelerBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64,
input, err := s.PackTxInputData(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createBridgeCellerErrorResponse(err)
}
contractAddress, err := s.GetContractAddress(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createBridgeCellerErrorResponse(err)
}
ethClient, err := s.rpcClient.EthClient(params.FromChain.ChainID)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createBridgeCellerErrorResponse(err)
}
ctx := context.Background()
@ -273,7 +276,7 @@ func (s *CelerBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64,
// this is an error we're facing otherwise: `execution reverted: ERC20: transfer amount exceeds allowance`
estimation = 350000
} else {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createBridgeCellerErrorResponse(err)
}
}
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
@ -304,10 +307,10 @@ func (s *CelerBridgeProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.T
func (s *CelerBridgeProcessor) GetContractAddress(params ProcessorInputParams) (common.Address, error) {
transferConfig, err := s.getTransferConfig(params.FromChain.IsTest)
if err != nil {
return common.Address{}, statusErrors.CreateErrorResponseFromError(err)
return common.Address{}, createBridgeCellerErrorResponse(err)
}
if transferConfig.Err != nil {
return common.Address{}, statusErrors.CreateErrorResponseFromError(errors.New(transferConfig.Err.Msg))
return common.Address{}, createBridgeCellerErrorResponse(errors.New(transferConfig.Err.Msg))
}
for _, chain := range transferConfig.Chains {
@ -332,16 +335,16 @@ func (s *CelerBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, s
FromChain: fromChain,
})
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
backend, err := s.rpcClient.EthClient(sendArgs.ChainID)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
contract, err := celer.NewCeler(addrs, backend)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
var tx *ethTypes.Transaction
@ -367,11 +370,11 @@ func (s *CelerBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, s
)
}
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeCellerErrorResponse(err)
}
err = s.transactor.StoreAndTrackPendingTx(txOpts.From, sendArgs.CbridgeTx.Symbol, sendArgs.ChainID, sendArgs.CbridgeTx.MultiTransactionID, tx)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeCellerErrorResponse(err)
}
return tx, nil
}
@ -379,7 +382,7 @@ func (s *CelerBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, s
func (s *CelerBridgeProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (types.Hash, error) {
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.CbridgeTx.From, verifiedAccount))
if err != nil {
return types.HexToHash(""), statusErrors.CreateErrorResponseFromError(err)
return types.HexToHash(""), createBridgeCellerErrorResponse(err)
}
return types.Hash(tx.Hash()), nil
@ -392,10 +395,10 @@ func (s *CelerBridgeProcessor) BuildTransaction(sendArgs *MultipathProcessorTxAr
func (s *CelerBridgeProcessor) CalculateAmountOut(params ProcessorInputParams) (*big.Int, error) {
amt, err := s.estimateAmt(params.FromChain, params.ToChain, params.AmountIn, params.FromToken.Symbol)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
if amt.Err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createBridgeCellerErrorResponse(err)
}
amountOut, _ := new(big.Int).SetString(amt.EqValueTokenAmt, 10)
return amountOut, nil

View File

@ -27,7 +27,6 @@ import (
hopL2ArbitrumBridge "github.com/status-im/status-go/contracts/hop/l2Contracts/l2ArbitrumBridge"
hopL2CctpImplementation "github.com/status-im/status-go/contracts/hop/l2Contracts/l2CctpImplementation"
hopL2OptimismBridge "github.com/status-im/status-go/contracts/hop/l2Contracts/l2OptimismBridge"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/rpc/chain"
@ -77,7 +76,7 @@ func (bf *BonderFee) UnmarshalJSON(data []byte) error {
}
if err := json.Unmarshal(data, aux); err != nil {
return statusErrors.CreateErrorResponseFromError(err)
return createBridgeHopErrorResponse(err)
}
bf.AmountIn = &bigint.BigInt{Int: new(big.Int)}
@ -126,6 +125,10 @@ func NewHopBridgeProcessor(rpcClient rpc.ClientInterface, transactor transaction
}
}
func createBridgeHopErrorResponse(err error) error {
return createErrorResponse(ProcessorBridgeHopName, err)
}
func (h *HopBridgeProcessor) Name() string {
return ProcessorBridgeHopName
}
@ -186,7 +189,7 @@ func (c *HopBridgeProcessor) getAppropriateABI(contractType string, chainID uint
func (h *HopBridgeProcessor) PackTxInputData(params ProcessorInputParams) ([]byte, error) {
_, contractType, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createBridgeHopErrorResponse(err)
}
return h.packTxInputDataInternally(params, contractType)
@ -195,7 +198,7 @@ func (h *HopBridgeProcessor) PackTxInputData(params ProcessorInputParams) ([]byt
func (h *HopBridgeProcessor) packTxInputDataInternally(params ProcessorInputParams, contractType string) ([]byte, error) {
abi, err := h.getAppropriateABI(contractType, params.FromChain.ChainID, params.FromToken)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createBridgeHopErrorResponse(err)
}
bonderKey := makeKey(params.FromChain.ChainID, params.ToChain.ChainID, "", "")
@ -238,17 +241,17 @@ func (h *HopBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64, e
contractAddress, contractType, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createBridgeHopErrorResponse(err)
}
input, err := h.packTxInputDataInternally(params, contractType)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createBridgeHopErrorResponse(err)
}
ethClient, err := h.contractMaker.RPCClient.EthClient(params.FromChain.ChainID)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createBridgeHopErrorResponse(err)
}
msg := ethereum.CallMsg{
@ -266,7 +269,7 @@ func (h *HopBridgeProcessor) EstimateGas(params ProcessorInputParams) (uint64, e
// this is an error we're facing otherwise: `execution reverted: ERC20: transfer amount exceeds allowance`
estimation = 350000
} else {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createBridgeHopErrorResponse(err)
}
}
@ -298,7 +301,7 @@ func (h *HopBridgeProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Tra
func (h *HopBridgeProcessor) GetContractAddress(params ProcessorInputParams) (common.Address, error) {
address, _, err := hop.GetContractAddress(params.FromChain.ChainID, params.FromToken.Symbol)
return address, statusErrors.CreateErrorResponseFromError(err)
return address, createBridgeHopErrorResponse(err)
}
func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
@ -311,7 +314,7 @@ func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, sig
nonce, err := h.transactor.NextNonce(h.contractMaker.RPCClient, fromChain.ChainID, sendArgs.HopTx.From)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
argNonce := hexutil.Uint64(nonce)
@ -324,12 +327,12 @@ func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, sig
ethClient, err := h.contractMaker.RPCClient.EthClient(fromChain.ChainID)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
contractAddress, contractType, err := hop.GetContractAddress(fromChain.ChainID, sendArgs.HopTx.Symbol)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
bonderKey := makeKey(sendArgs.HopTx.ChainID, sendArgs.HopTx.ChainIDTo, "", "")
@ -354,11 +357,11 @@ func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, sig
return tx, ErrContractTypeNotSupported
}
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
err = h.transactor.StoreAndTrackPendingTx(txOpts.From, sendArgs.HopTx.Symbol, sendArgs.ChainID, sendArgs.HopTx.MultiTransactionID, tx)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return tx, nil
}
@ -366,7 +369,7 @@ func (h *HopBridgeProcessor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, sig
func (h *HopBridgeProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
tx, err := h.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.HopTx.From, verifiedAccount))
if err != nil {
return types.Hash{}, statusErrors.CreateErrorResponseFromError(err)
return types.Hash{}, createBridgeHopErrorResponse(err)
}
return types.Hash(tx.Hash()), nil
}
@ -427,7 +430,7 @@ func (h *HopBridgeProcessor) CalculateFees(params ProcessorInputParams) (*big.In
bonderFee := &BonderFee{}
err = json.Unmarshal(response, bonderFee)
if err != nil {
return nil, nil, statusErrors.CreateErrorResponseFromError(err)
return nil, nil, createBridgeHopErrorResponse(err)
}
h.bonderFee.Store(bonderKey, bonderFee)
@ -465,7 +468,7 @@ func (h *HopBridgeProcessor) sendCctpL1BridgeTx(contractAddress common.Address,
ethClient,
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return contractInstance.Send(
@ -495,7 +498,7 @@ func (h *HopBridgeProcessor) sendL1BridgeTx(contractAddress common.Address, ethC
ethClient,
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return contractInstance.SendToL2(
@ -515,7 +518,7 @@ func (h *HopBridgeProcessor) sendL1BridgeTx(contractAddress common.Address, ethC
ethClient,
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return contractInstance.SendToL2(
@ -534,7 +537,7 @@ func (h *HopBridgeProcessor) sendL1BridgeTx(contractAddress common.Address, ethC
ethClient,
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return contractInstance.SendToL2(
@ -564,7 +567,7 @@ func (h *HopBridgeProcessor) sendCctpL2BridgeTx(contractAddress common.Address,
ethClient,
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return contractInstance.Send(
@ -595,7 +598,7 @@ func (h *HopBridgeProcessor) sendL2AmmWrapperTx(contractAddress common.Address,
ethClient,
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return contractInstance.SwapAndSend(
@ -630,7 +633,7 @@ func (h *HopBridgeProcessor) sendL2BridgeTx(contractAddress common.Address, ethC
ethClient,
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return contractInstance.Send(
@ -649,7 +652,7 @@ func (h *HopBridgeProcessor) sendL2BridgeTx(contractAddress common.Address, ethC
ethClient,
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createBridgeHopErrorResponse(err)
}
return contractInstance.Send(

View File

@ -13,7 +13,6 @@ import (
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/contracts"
"github.com/status-im/status-go/contracts/resolver"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/services/ens"
@ -37,6 +36,10 @@ func NewENSPublicKeyProcessor(rpcClient *rpc.Client, transactor transactions.Tra
}
}
func createENSPublicKeyErrorResponse(err error) error {
return createErrorResponse(ProcessorENSPublicKeyName, err)
}
func (s *ENSPublicKeyProcessor) Name() string {
return ProcessorENSPublicKeyName
}
@ -52,7 +55,7 @@ func (s *ENSPublicKeyProcessor) CalculateFees(params ProcessorInputParams) (*big
func (s *ENSPublicKeyProcessor) PackTxInputData(params ProcessorInputParams) ([]byte, error) {
resolverABI, err := abi.JSON(strings.NewReader(resolver.PublicResolverABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createENSPublicKeyErrorResponse(err)
}
x, y := ens.ExtractCoordinates(params.PublicKey)
@ -71,12 +74,12 @@ func (s *ENSPublicKeyProcessor) EstimateGas(params ProcessorInputParams) (uint64
contractAddress, err := s.GetContractAddress(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSPublicKeyErrorResponse(err)
}
input, err := s.PackTxInputData(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSPublicKeyErrorResponse(err)
}
ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID)
@ -93,7 +96,7 @@ func (s *ENSPublicKeyProcessor) EstimateGas(params ProcessorInputParams) (uint64
estimation, err := ethClient.EstimateGas(context.Background(), msg)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSPublicKeyErrorResponse(err)
}
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
@ -105,7 +108,7 @@ func (s *ENSPublicKeyProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.
toAddr := types.Address(params.ToAddr)
inputData, err := s.PackTxInputData(params)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createENSPublicKeyErrorResponse(err)
}
sendArgs := &MultipathProcessorTxArgs{
@ -136,7 +139,7 @@ func (s *ENSPublicKeyProcessor) CalculateAmountOut(params ProcessorInputParams)
func (s *ENSPublicKeyProcessor) GetContractAddress(params ProcessorInputParams) (common.Address, error) {
addr, err := s.ensService.API().Resolver(context.Background(), params.FromChain.ChainID, params.Username)
if err != nil {
return common.Address{}, statusErrors.CreateErrorResponseFromError(err)
return common.Address{}, createENSPublicKeyErrorResponse(err)
}
if *addr == ZeroAddress {
return common.Address{}, ErrENSResolverNotFound

View File

@ -15,7 +15,6 @@ import (
"github.com/status-im/status-go/contracts"
"github.com/status-im/status-go/contracts/registrar"
"github.com/status-im/status-go/contracts/snt"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/services/ens"
@ -39,6 +38,10 @@ func NewENSRegisterProcessor(rpcClient *rpc.Client, transactor transactions.Tran
}
}
func createENSRegisterProcessorErrorResponse(err error) error {
return createErrorResponse(ProcessorENSRegisterName, err)
}
func (s *ENSRegisterProcessor) Name() string {
return ProcessorENSRegisterName
}
@ -46,11 +49,11 @@ func (s *ENSRegisterProcessor) Name() string {
func (s *ENSRegisterProcessor) GetPriceForRegisteringEnsName(chainID uint64) (*big.Int, error) {
registryAddr, err := s.ensService.API().GetRegistrarAddress(context.Background(), chainID)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createENSRegisterProcessorErrorResponse(err)
}
registrar, err := s.contractMaker.NewUsernameRegistrar(chainID, registryAddr)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createENSRegisterProcessorErrorResponse(err)
}
callOpts := &bind.CallOpts{Context: context.Background(), Pending: false}
@ -68,28 +71,28 @@ func (s *ENSRegisterProcessor) CalculateFees(params ProcessorInputParams) (*big.
func (s *ENSRegisterProcessor) PackTxInputData(params ProcessorInputParams) ([]byte, error) {
price, err := s.GetPriceForRegisteringEnsName(params.FromChain.ChainID)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createENSRegisterProcessorErrorResponse(err)
}
registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createENSRegisterProcessorErrorResponse(err)
}
x, y := ens.ExtractCoordinates(params.PublicKey)
extraData, err := registrarABI.Pack("register", ens.UsernameToLabel(params.Username), params.FromAddr, x, y)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createENSRegisterProcessorErrorResponse(err)
}
sntABI, err := abi.JSON(strings.NewReader(snt.SNTABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createENSRegisterProcessorErrorResponse(err)
}
registryAddr, err := s.ensService.API().GetRegistrarAddress(context.Background(), params.FromChain.ChainID)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createENSRegisterProcessorErrorResponse(err)
}
return sntABI.Pack("approveAndCall", registryAddr, price, extraData)
@ -107,17 +110,17 @@ func (s *ENSRegisterProcessor) EstimateGas(params ProcessorInputParams) (uint64,
contractAddress, err := s.GetContractAddress(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSRegisterProcessorErrorResponse(err)
}
input, err := s.PackTxInputData(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSRegisterProcessorErrorResponse(err)
}
ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSRegisterProcessorErrorResponse(err)
}
msg := ethereum.CallMsg{
@ -129,7 +132,7 @@ func (s *ENSRegisterProcessor) EstimateGas(params ProcessorInputParams) (uint64,
estimation, err := ethClient.EstimateGas(context.Background(), msg)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSRegisterProcessorErrorResponse(err)
}
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
@ -141,7 +144,7 @@ func (s *ENSRegisterProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.T
toAddr := types.Address(params.ToAddr)
inputData, err := s.PackTxInputData(params)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createENSRegisterProcessorErrorResponse(err)
}
sendArgs := &MultipathProcessorTxArgs{

View File

@ -13,7 +13,6 @@ import (
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/contracts"
"github.com/status-im/status-go/contracts/registrar"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/services/ens"
@ -37,6 +36,10 @@ func NewENSReleaseProcessor(rpcClient *rpc.Client, transactor transactions.Trans
}
}
func createENSReleaseErrorResponse(err error) error {
return createErrorResponse(ProcessorENSReleaseName, err)
}
func (s *ENSReleaseProcessor) Name() string {
return ProcessorENSReleaseName
}
@ -52,7 +55,7 @@ func (s *ENSReleaseProcessor) CalculateFees(params ProcessorInputParams) (*big.I
func (s *ENSReleaseProcessor) PackTxInputData(params ProcessorInputParams) ([]byte, error) {
registrarABI, err := abi.JSON(strings.NewReader(registrar.UsernameRegistrarABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createENSReleaseErrorResponse(err)
}
return registrarABI.Pack("release", ens.UsernameToLabel(params.Username))
@ -70,17 +73,17 @@ func (s *ENSReleaseProcessor) EstimateGas(params ProcessorInputParams) (uint64,
contractAddress, err := s.GetContractAddress(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSReleaseErrorResponse(err)
}
input, err := s.PackTxInputData(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSReleaseErrorResponse(err)
}
ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSReleaseErrorResponse(err)
}
msg := ethereum.CallMsg{
@ -92,7 +95,7 @@ func (s *ENSReleaseProcessor) EstimateGas(params ProcessorInputParams) (uint64,
estimation, err := ethClient.EstimateGas(context.Background(), msg)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createENSReleaseErrorResponse(err)
}
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
@ -104,7 +107,7 @@ func (s *ENSReleaseProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Tr
toAddr := types.Address(params.ToAddr)
inputData, err := s.PackTxInputData(params)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createENSReleaseErrorResponse(err)
}
sendArgs := &MultipathProcessorTxArgs{

View File

@ -14,7 +14,6 @@ import (
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/contracts/ierc1155"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/transactions"
@ -36,6 +35,10 @@ func NewERC1155Processor(rpcClient *rpc.Client, transactor transactions.Transact
return &ERC1155Processor{rpcClient: rpcClient, transactor: transactor}
}
func createERC1155ErrorResponse(err error) error {
return createErrorResponse(ProcessorERC1155Name, err)
}
func (s *ERC1155Processor) Name() string {
return ProcessorERC1155Name
}
@ -51,12 +54,12 @@ func (s *ERC1155Processor) CalculateFees(params ProcessorInputParams) (*big.Int,
func (s *ERC1155Processor) PackTxInputData(params ProcessorInputParams) ([]byte, error) {
abi, err := abi.JSON(strings.NewReader(ierc1155.Ierc1155ABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createERC1155ErrorResponse(err)
}
id, success := big.NewInt(0).SetString(params.FromToken.Symbol, 0)
if !success {
return []byte{}, statusErrors.CreateErrorResponseFromError(fmt.Errorf("failed to convert %s to big.Int", params.FromToken.Symbol))
return []byte{}, createERC1155ErrorResponse(fmt.Errorf("failed to convert %s to big.Int", params.FromToken.Symbol))
}
return abi.Pack("safeTransferFrom",
@ -80,14 +83,14 @@ func (s *ERC1155Processor) EstimateGas(params ProcessorInputParams) (uint64, err
ethClient, err := s.rpcClient.EthClient(params.FromChain.ChainID)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createERC1155ErrorResponse(err)
}
value := new(big.Int)
input, err := s.PackTxInputData(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createERC1155ErrorResponse(err)
}
msg := ethereum.CallMsg{
@ -99,7 +102,7 @@ func (s *ERC1155Processor) EstimateGas(params ProcessorInputParams) (uint64, err
estimation, err := ethClient.EstimateGas(context.Background(), msg)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createERC1155ErrorResponse(err)
}
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
return uint64(increasedEstimation), nil
@ -111,7 +114,7 @@ func (s *ERC1155Processor) BuildTx(params ProcessorInputParams) (*ethTypes.Trans
// We store ERC1155 Token ID using big.Int.String() in token.Symbol
tokenID, success := new(big.Int).SetString(params.FromToken.Symbol, 10)
if !success {
return nil, statusErrors.CreateErrorResponseFromError(fmt.Errorf("failed to convert ERC1155's Symbol %s to big.Int", params.FromToken.Symbol))
return nil, createERC1155ErrorResponse(fmt.Errorf("failed to convert ERC1155's Symbol %s to big.Int", params.FromToken.Symbol))
}
sendArgs := &MultipathProcessorTxArgs{
@ -135,17 +138,17 @@ func (s *ERC1155Processor) BuildTx(params ProcessorInputParams) (*ethTypes.Trans
func (s *ERC1155Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
ethClient, err := s.rpcClient.EthClient(sendArgs.ChainID)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC1155ErrorResponse(err)
}
contract, err := ierc1155.NewIerc1155(common.Address(*sendArgs.ERC1155TransferTx.To), ethClient)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC1155ErrorResponse(err)
}
nonce, err := s.transactor.NextNonce(s.rpcClient, sendArgs.ChainID, sendArgs.ERC1155TransferTx.From)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC1155ErrorResponse(err)
}
argNonce := hexutil.Uint64(nonce)
@ -160,11 +163,11 @@ func (s *ERC1155Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signe
[]byte{},
)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC1155ErrorResponse(err)
}
err = s.transactor.StoreAndTrackPendingTx(from, sendArgs.ERC1155TransferTx.Symbol, sendArgs.ChainID, sendArgs.ERC1155TransferTx.MultiTransactionID, tx)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC1155ErrorResponse(err)
}
return tx, nil
}
@ -172,7 +175,7 @@ func (s *ERC1155Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signe
func (s *ERC1155Processor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.ERC1155TransferTx.From, verifiedAccount))
if err != nil {
return hash, statusErrors.CreateErrorResponseFromError(err)
return hash, createERC1155ErrorResponse(err)
}
return types.Hash(tx.Hash()), nil
}

View File

@ -14,7 +14,6 @@ import (
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/contracts/community-tokens/collectibles"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/transactions"
@ -35,6 +34,10 @@ func NewERC721Processor(rpcClient *rpc.Client, transactor transactions.Transacto
return &ERC721Processor{rpcClient: rpcClient, transactor: transactor}
}
func createERC721ErrorResponse(err error) error {
return createErrorResponse(ProcessorERC721Name, err)
}
func (s *ERC721Processor) Name() string {
return ProcessorERC721Name
}
@ -50,12 +53,12 @@ func (s *ERC721Processor) CalculateFees(params ProcessorInputParams) (*big.Int,
func (s *ERC721Processor) PackTxInputData(params ProcessorInputParams) ([]byte, error) {
abi, err := abi.JSON(strings.NewReader(collectibles.CollectiblesMetaData.ABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createERC721ErrorResponse(err)
}
id, success := big.NewInt(0).SetString(params.FromToken.Symbol, 0)
if !success {
return []byte{}, statusErrors.CreateErrorResponseFromError(fmt.Errorf("failed to convert %s to big.Int", params.FromToken.Symbol))
return []byte{}, createERC721ErrorResponse(fmt.Errorf("failed to convert %s to big.Int", params.FromToken.Symbol))
}
return abi.Pack("safeTransferFrom",
@ -77,14 +80,14 @@ func (s *ERC721Processor) EstimateGas(params ProcessorInputParams) (uint64, erro
ethClient, err := s.rpcClient.EthClient(params.FromChain.ChainID)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createERC721ErrorResponse(err)
}
value := new(big.Int)
input, err := s.PackTxInputData(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createERC721ErrorResponse(err)
}
msg := ethereum.CallMsg{
@ -96,7 +99,7 @@ func (s *ERC721Processor) EstimateGas(params ProcessorInputParams) (uint64, erro
estimation, err := ethClient.EstimateGas(context.Background(), msg)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createERC721ErrorResponse(err)
}
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
@ -109,7 +112,7 @@ func (s *ERC721Processor) BuildTx(params ProcessorInputParams) (*ethTypes.Transa
// We store ERC721 Token ID using big.Int.String() in token.Symbol
tokenID, success := new(big.Int).SetString(params.FromToken.Symbol, 10)
if !success {
return nil, statusErrors.CreateErrorResponseFromError(fmt.Errorf("failed to convert ERC721's Symbol %s to big.Int", params.FromToken.Symbol))
return nil, createERC721ErrorResponse(fmt.Errorf("failed to convert ERC721's Symbol %s to big.Int", params.FromToken.Symbol))
}
sendArgs := &MultipathProcessorTxArgs{
@ -132,17 +135,17 @@ func (s *ERC721Processor) BuildTx(params ProcessorInputParams) (*ethTypes.Transa
func (s *ERC721Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signerFn bind.SignerFn) (tx *ethTypes.Transaction, err error) {
ethClient, err := s.rpcClient.EthClient(sendArgs.ChainID)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC721ErrorResponse(err)
}
contract, err := collectibles.NewCollectibles(common.Address(*sendArgs.ERC721TransferTx.To), ethClient)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC721ErrorResponse(err)
}
nonce, err := s.transactor.NextNonce(s.rpcClient, sendArgs.ChainID, sendArgs.ERC721TransferTx.From)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC721ErrorResponse(err)
}
argNonce := hexutil.Uint64(nonce)
@ -153,11 +156,11 @@ func (s *ERC721Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signer
sendArgs.ERC721TransferTx.Recipient,
sendArgs.ERC721TransferTx.TokenID.ToInt())
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC721ErrorResponse(err)
}
err = s.transactor.StoreAndTrackPendingTx(from, sendArgs.ERC721TransferTx.Symbol, sendArgs.ChainID, sendArgs.ERC721TransferTx.MultiTransactionID, tx)
if err != nil {
return tx, statusErrors.CreateErrorResponseFromError(err)
return tx, createERC721ErrorResponse(err)
}
return tx, nil
}
@ -165,7 +168,7 @@ func (s *ERC721Processor) sendOrBuild(sendArgs *MultipathProcessorTxArgs, signer
func (s *ERC721Processor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (hash types.Hash, err error) {
tx, err := s.sendOrBuild(sendArgs, getSigner(sendArgs.ChainID, sendArgs.ERC721TransferTx.From, verifiedAccount))
if err != nil {
return hash, statusErrors.CreateErrorResponseFromError(err)
return hash, createERC721ErrorResponse(err)
}
return types.Hash(tx.Hash()), nil
}

View File

@ -15,7 +15,6 @@ import (
"github.com/status-im/status-go/contracts"
"github.com/status-im/status-go/contracts/snt"
stickersContracts "github.com/status-im/status-go/contracts/stickers"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/services/stickers"
@ -39,6 +38,10 @@ func NewStickersBuyProcessor(rpcClient *rpc.Client, transactor transactions.Tran
}
}
func createStickersBuyErrorResponse(err error) error {
return createErrorResponse(ProcessorStickersBuyName, err)
}
func (s *StickersBuyProcessor) Name() string {
return ProcessorStickersBuyName
}
@ -54,34 +57,34 @@ func (s *StickersBuyProcessor) CalculateFees(params ProcessorInputParams) (*big.
func (s *StickersBuyProcessor) PackTxInputData(params ProcessorInputParams) ([]byte, error) {
stickerType, err := s.contractMaker.NewStickerType(params.FromChain.ChainID)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createStickersBuyErrorResponse(err)
}
callOpts := &bind.CallOpts{Context: context.Background(), Pending: false}
packInfo, err := stickerType.GetPackData(callOpts, params.PackID)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createStickersBuyErrorResponse(err)
}
stickerMarketABI, err := abi.JSON(strings.NewReader(stickersContracts.StickerMarketABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createStickersBuyErrorResponse(err)
}
extraData, err := stickerMarketABI.Pack("buyToken", params.PackID, params.FromAddr, packInfo.Price)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createStickersBuyErrorResponse(err)
}
sntABI, err := abi.JSON(strings.NewReader(snt.SNTABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createStickersBuyErrorResponse(err)
}
stickerMarketAddress, err := stickersContracts.StickerMarketContractAddress(params.FromChain.ChainID)
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createStickersBuyErrorResponse(err)
}
return sntABI.Pack("approveAndCall", stickerMarketAddress, packInfo.Price, extraData)
@ -99,17 +102,17 @@ func (s *StickersBuyProcessor) EstimateGas(params ProcessorInputParams) (uint64,
contractAddress, err := s.GetContractAddress(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createStickersBuyErrorResponse(err)
}
input, err := s.PackTxInputData(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createStickersBuyErrorResponse(err)
}
ethClient, err := s.contractMaker.RPCClient.EthClient(params.FromChain.ChainID)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createStickersBuyErrorResponse(err)
}
msg := ethereum.CallMsg{
@ -121,7 +124,7 @@ func (s *StickersBuyProcessor) EstimateGas(params ProcessorInputParams) (uint64,
estimation, err := ethClient.EstimateGas(context.Background(), msg)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createStickersBuyErrorResponse(err)
}
increasedEstimation := float64(estimation) * IncreaseEstimatedGasFactor
@ -133,7 +136,7 @@ func (s *StickersBuyProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.T
toAddr := types.Address(params.ToAddr)
inputData, err := s.PackTxInputData(params)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createStickersBuyErrorResponse(err)
}
sendArgs := &MultipathProcessorTxArgs{

View File

@ -10,7 +10,6 @@ import (
"github.com/ethereum/go-ethereum/common/hexutil"
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/account"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
walletCommon "github.com/status-im/status-go/services/wallet/common"
@ -42,6 +41,16 @@ func NewSwapParaswapProcessor(rpcClient *rpc.Client, transactor transactions.Tra
}
}
func createSwapParaswapErrorResponse(err error) error {
switch err.Error() {
case "Price Timeout":
return ErrPriceTimeout
case "No routes found with enough liquidity":
return ErrNotEnoughLiquidity
}
return createErrorResponse(ProcessorSwapParaswapName, err)
}
func (s *SwapParaswapProcessor) Name() string {
return ProcessorSwapParaswapName
}
@ -73,7 +82,7 @@ func (s *SwapParaswapProcessor) AvailableFor(params ProcessorInputParams) (bool,
if searchForToToken || searchForToken {
tokensList, err := s.paraswapClient.FetchTokensList(context.Background())
if err != nil {
return false, statusErrors.CreateErrorResponseFromError(err)
return false, createSwapParaswapErrorResponse(err)
}
for _, t := range tokensList {
@ -129,7 +138,7 @@ func (s *SwapParaswapProcessor) EstimateGas(params ProcessorInputParams) (uint64
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, swapSide)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createSwapParaswapErrorResponse(err)
}
key := makeKey(params.FromChain.ChainID, params.ToChain.ChainID, params.FromToken.Symbol, params.ToToken.Symbol)
@ -187,7 +196,7 @@ func (s *SwapParaswapProcessor) prepareTransaction(sendArgs *MultipathProcessorT
common.Address(sendArgs.SwapTx.From), common.Address(*sendArgs.SwapTx.To),
priceRoute.RawPriceRoute, priceRoute.Side)
if err != nil {
return statusErrors.CreateErrorResponseFromError(err)
return createSwapParaswapErrorResponse(err)
}
value, ok := new(big.Int).SetString(tx.Value, 10)
@ -197,7 +206,7 @@ func (s *SwapParaswapProcessor) prepareTransaction(sendArgs *MultipathProcessorT
gas, err := strconv.ParseUint(tx.Gas, 10, 64)
if err != nil {
return statusErrors.CreateErrorResponseFromError(err)
return createSwapParaswapErrorResponse(err)
}
gasPrice, ok := new(big.Int).SetString(tx.GasPrice, 10)
@ -221,7 +230,7 @@ func (s *SwapParaswapProcessor) prepareTransaction(sendArgs *MultipathProcessorT
func (s *SwapParaswapProcessor) BuildTransaction(sendArgs *MultipathProcessorTxArgs) (*ethTypes.Transaction, error) {
err := s.prepareTransaction(sendArgs)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createSwapParaswapErrorResponse(err)
}
return s.transactor.ValidateAndBuildTransaction(sendArgs.ChainID, sendArgs.SwapTx.SendTxArgs)
}
@ -229,7 +238,7 @@ func (s *SwapParaswapProcessor) BuildTransaction(sendArgs *MultipathProcessorTxA
func (s *SwapParaswapProcessor) Send(sendArgs *MultipathProcessorTxArgs, verifiedAccount *account.SelectedExtKey) (types.Hash, error) {
err := s.prepareTransaction(sendArgs)
if err != nil {
return types.Hash{}, statusErrors.CreateErrorResponseFromError(err)
return types.Hash{}, createSwapParaswapErrorResponse(err)
}
return s.transactor.SendTransactionWithChainID(sendArgs.ChainID, sendArgs.SwapTx.SendTxArgs, verifiedAccount)

View File

@ -12,7 +12,6 @@ import (
ethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/status-im/status-go/account"
"github.com/status-im/status-go/contracts/ierc20"
statusErrors "github.com/status-im/status-go/errors"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/rpc"
"github.com/status-im/status-go/transactions"
@ -27,6 +26,10 @@ func NewTransferProcessor(rpcClient *rpc.Client, transactor transactions.Transac
return &TransferProcessor{rpcClient: rpcClient, transactor: transactor}
}
func createTransferErrorResponse(err error) error {
return createErrorResponse(ProcessorTransferName, err)
}
func (s *TransferProcessor) Name() string {
return ProcessorTransferName
}
@ -54,7 +57,7 @@ func (s *TransferProcessor) PackTxInputData(params ProcessorInputParams) ([]byte
} else {
abi, err := abi.JSON(strings.NewReader(ierc20.IERC20ABI))
if err != nil {
return []byte{}, statusErrors.CreateErrorResponseFromError(err)
return []byte{}, createTransferErrorResponse(err)
}
return abi.Pack("transfer",
params.ToAddr,
@ -78,18 +81,18 @@ func (s *TransferProcessor) EstimateGas(params ProcessorInputParams) (uint64, er
input, err := s.PackTxInputData(params)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createTransferErrorResponse(err)
}
if params.FromToken.IsNative() {
estimation, err = s.transactor.EstimateGas(params.FromChain, params.FromAddr, params.ToAddr, params.AmountIn, input)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createTransferErrorResponse(err)
}
} else {
ethClient, err := s.rpcClient.EthClient(params.FromChain.ChainID)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createTransferErrorResponse(err)
}
ctx := context.Background()
@ -102,7 +105,7 @@ func (s *TransferProcessor) EstimateGas(params ProcessorInputParams) (uint64, er
estimation, err = ethClient.EstimateGas(ctx, msg)
if err != nil {
return 0, statusErrors.CreateErrorResponseFromError(err)
return 0, createTransferErrorResponse(err)
}
}
@ -128,14 +131,14 @@ func (s *TransferProcessor) BuildTx(params ProcessorInputParams) (*ethTypes.Tran
}
abi, err := abi.JSON(strings.NewReader(ierc20.IERC20ABI))
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createTransferErrorResponse(err)
}
input, err := abi.Pack("transfer",
params.ToAddr,
params.AmountIn,
)
if err != nil {
return nil, statusErrors.CreateErrorResponseFromError(err)
return nil, createTransferErrorResponse(err)
}
sendArgs := &MultipathProcessorTxArgs{
TransferTx: &transactions.SendTxArgs{

View File

@ -10,6 +10,7 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/log"
"github.com/status-im/status-go/errors"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/services/ens"
@ -121,6 +122,11 @@ type PathV2 struct {
requiredNativeBalance *big.Int
}
type ProcessorError struct {
ProcessorName string
Error error
}
func (p *PathV2) Equal(o *PathV2) bool {
return p.FromChain.ChainID == o.FromChain.ChainID && p.ToChain.ChainID == o.ToChain.ChainID
}
@ -507,12 +513,24 @@ func (r *Router) SuggestedRoutesV2(ctx context.Context, input *RouteInputParams)
return nil, errors.CreateErrorResponseFromError(err)
}
candidates, err := r.resolveCandidates(ctx, input, selectedFromChains, selectedTohains, balanceMap)
candidates, processorErrors, err := r.resolveCandidates(ctx, input, selectedFromChains, selectedTohains, balanceMap)
if err != nil {
return nil, errors.CreateErrorResponseFromError(err)
}
return r.resolveRoutes(ctx, input, candidates, balanceMap)
suggestedRoutes, err := r.resolveRoutes(ctx, input, candidates, balanceMap)
if err == nil && (suggestedRoutes == nil || len(suggestedRoutes.Best) == 0) {
// No best route found, but no error given.
if len(processorErrors) > 0 {
// Return one of the path processor errors if present.
err = errors.CreateErrorResponseFromError(processorErrors[0].Error)
} else {
err = ErrNoBestRouteFound
}
}
return suggestedRoutes, err
}
// getBalanceMapForTokenOnChains returns the balance map for passed address, where the key is in format "chainID-tokenSymbol" and
@ -722,7 +740,7 @@ func (r *Router) getSelectedChains(input *RouteInputParams) (selectedFromChains
}
func (r *Router) resolveCandidates(ctx context.Context, input *RouteInputParams, selectedFromChains []*params.Network,
selectedTohains []*params.Network, balanceMap map[string]*big.Int) (candidates []*PathV2, err error) {
selectedTohains []*params.Network, balanceMap map[string]*big.Int) (candidates []*PathV2, processorErrors []*ProcessorError, err error) {
var (
testsMode = input.testsMode && input.testParams != nil
group = async.NewAtomicGroup(ctx)
@ -731,7 +749,23 @@ func (r *Router) resolveCandidates(ctx context.Context, input *RouteInputParams,
crossChainAmountOptions, err := r.findOptionsForSendingAmount(input, selectedFromChains, balanceMap)
if err != nil {
return nil, errors.CreateErrorResponseFromError(err)
return nil, nil, errors.CreateErrorResponseFromError(err)
}
appendProcessorErrorFn := func(processorName string, err error) {
log.Error("routerv2.resolveCandidates error", "processor", processorName, "err", err)
mu.Lock()
defer mu.Unlock()
processorErrors = append(processorErrors, &ProcessorError{
ProcessorName: processorName,
Error: err,
})
}
appendPathFn := func(path *PathV2) {
mu.Lock()
defer mu.Unlock()
candidates = append(candidates, path)
}
for networkIdx := range selectedFromChains {
@ -825,26 +859,34 @@ func (r *Router) resolveCandidates(ctx context.Context, input *RouteInputParams,
}
can, err := pProcessor.AvailableFor(processorInputParams)
if err != nil || !can {
if err != nil {
appendProcessorErrorFn(pProcessor.Name(), err)
continue
}
if !can {
continue
}
bonderFees, tokenFees, err := pProcessor.CalculateFees(processorInputParams)
if err != nil {
appendProcessorErrorFn(pProcessor.Name(), err)
continue
}
gasLimit, err := pProcessor.EstimateGas(processorInputParams)
if err != nil {
appendProcessorErrorFn(pProcessor.Name(), err)
continue
}
approvalContractAddress, err := pProcessor.GetContractAddress(processorInputParams)
if err != nil {
appendProcessorErrorFn(pProcessor.Name(), err)
continue
}
approvalRequired, approvalAmountRequired, approvalGasLimit, l1ApprovalFee, err := r.requireApproval(ctx, input.SendType, &approvalContractAddress, processorInputParams)
if err != nil {
appendProcessorErrorFn(pProcessor.Name(), err)
continue
}
@ -861,6 +903,7 @@ func (r *Router) resolveCandidates(ctx context.Context, input *RouteInputParams,
amountOut, err := pProcessor.CalculateAmountOut(processorInputParams)
if err != nil {
appendProcessorErrorFn(pProcessor.Name(), err)
continue
}
@ -871,8 +914,7 @@ func (r *Router) resolveCandidates(ctx context.Context, input *RouteInputParams,
estimatedTime += 1
}
mu.Lock()
candidates = append(candidates, &PathV2{
appendPathFn(&PathV2{
ProcessorName: pProcessor.Name(),
FromChain: network,
ToChain: dest,
@ -901,7 +943,6 @@ func (r *Router) resolveCandidates(ctx context.Context, input *RouteInputParams,
EstimatedTime: estimatedTime,
})
mu.Unlock()
}
}
}
@ -910,7 +951,7 @@ func (r *Router) resolveCandidates(ctx context.Context, input *RouteInputParams,
}
group.Wait()
return candidates, nil
return candidates, processorErrors, nil
}
func (r *Router) checkBalancesForTheBestRoute(ctx context.Context, bestRoute []*PathV2, input *RouteInputParams, balanceMap map[string]*big.Int) (err error) {

View File

@ -60,6 +60,9 @@ func amountOptionsMapsEqual(map1, map2 map[uint64][]amountOption) bool {
func assertPathsEqual(t *testing.T, expected, actual []*PathV2) {
assert.Equal(t, len(expected), len(actual))
if len(expected) == 0 {
return
}
for _, c := range actual {
found := false
@ -167,7 +170,11 @@ func TestRouterV2(t *testing.T) {
if tt.expectedError != nil {
assert.Error(t, err)
assert.Equal(t, tt.expectedError.Error(), err.Error())
assert.Nil(t, routes)
if routes == nil {
assert.Empty(t, tt.expectedCandidates)
} else {
assertPathsEqual(t, tt.expectedCandidates, routes.Candidates)
}
} else {
assert.NoError(t, err)
assertPathsEqual(t, tt.expectedCandidates, routes.Candidates)

View File

@ -772,6 +772,7 @@ func getNormalTestParamsList() []normalTestParams {
approvalL1Fee: testApprovalL1Fee,
},
},
expectedError: ErrNoBestRouteFound,
expectedCandidates: []*PathV2{},
},
{
@ -1760,6 +1761,7 @@ func getNormalTestParamsList() []normalTestParams {
approvalL1Fee: testApprovalL1Fee,
},
},
expectedError: ErrNoBestRouteFound,
expectedCandidates: []*PathV2{},
},
{
@ -2258,6 +2260,7 @@ func getNormalTestParamsList() []normalTestParams {
approvalL1Fee: testApprovalL1Fee,
},
},
expectedError: ErrNoBestRouteFound,
expectedCandidates: []*PathV2{},
},
{
@ -2329,6 +2332,7 @@ func getNormalTestParamsList() []normalTestParams {
approvalL1Fee: testApprovalL1Fee,
},
},
expectedError: ErrNoBestRouteFound,
expectedCandidates: []*PathV2{},
},
{
@ -2445,6 +2449,7 @@ func getNormalTestParamsList() []normalTestParams {
approvalL1Fee: testApprovalL1Fee,
},
},
expectedError: ErrNoBestRouteFound,
expectedCandidates: []*PathV2{},
},
}