diff --git a/tequilapi/contract/transactor.go b/tequilapi/contract/transactor.go index 988abf639c..fd2f077c2d 100644 --- a/tequilapi/contract/transactor.go +++ b/tequilapi/contract/transactor.go @@ -18,11 +18,14 @@ package contract import ( + "errors" + "fmt" "math/big" "net/http" "time" "github.com/mysteriumnetwork/node/core/beneficiary" + "github.com/mysteriumnetwork/payments/crypto" "github.com/ethereum/go-ethereum/common" "github.com/go-openapi/strfmt" @@ -235,6 +238,47 @@ type WithdrawRequest struct { Amount string `json:"amount,omitempty"` } +// Validate will validate a given request +func (w *WithdrawRequest) Validate() error { + zeroAddr := common.HexToAddress("").Hex() + if !common.IsHexAddress(w.HermesID) || w.HermesID == zeroAddr { + return errors.New("hermesID should be a valid hex address") + } + if !common.IsHexAddress(w.ProviderID) || w.ProviderID == zeroAddr { + return errors.New("providerID should be a valid hex address") + } + if !common.IsHexAddress(w.Beneficiary) || w.Beneficiary == zeroAddr { + return errors.New("beneficiary should be a valid hex address") + } + + amount, err := w.AmountInMYST() + if err != nil { + return err + } + + if amount != nil && amount.Cmp(crypto.FloatToBigMyst(99)) > 0 { + return errors.New("withdrawal amount cannot be more than 99 MYST") + } + + return nil +} + +// AmountInMYST will return the amount value converted to big.Int MYST. +// +// Amount can be `nil` +func (w *WithdrawRequest) AmountInMYST() (*big.Int, error) { + if w.Amount == "" { + return nil, nil + } + + res, ok := big.NewInt(0).SetString(w.Amount, 10) + if !ok { + return nil, fmt.Errorf("%v is not a valid integer", w.Amount) + } + + return res, nil +} + // SettleWithBeneficiaryRequest represent the request to settle with new beneficiary address. type SettleWithBeneficiaryRequest struct { SettleRequest diff --git a/tequilapi/endpoints/transactor.go b/tequilapi/endpoints/transactor.go index 950ab72e98..96c7c30e4a 100644 --- a/tequilapi/endpoints/transactor.go +++ b/tequilapi/endpoints/transactor.go @@ -37,7 +37,6 @@ import ( "github.com/mysteriumnetwork/node/session/pingpong" "github.com/mysteriumnetwork/node/tequilapi/contract" "github.com/mysteriumnetwork/node/tequilapi/utils" - "github.com/mysteriumnetwork/payments/crypto" "github.com/pkg/errors" "github.com/rs/zerolog/log" "github.com/vcraescu/go-paginator/adapter" @@ -452,22 +451,21 @@ func (te *transactorEndpoint) Withdraw(c *gin.Context) { resp := c.Writer request := c.Request - req := contract.WithdrawRequest{} - + var req contract.WithdrawRequest err := json.NewDecoder(request.Body).Decode(&req) if err != nil { utils.SendError(resp, err, http.StatusBadRequest) return } - amount, err := te.parseWithdrawalAmount(req.Amount) - if err != nil { + if err := req.Validate(); err != nil { utils.SendError(resp, err, http.StatusBadRequest) return } - if amount != nil && amount.Cmp(crypto.FloatToBigMyst(99)) > 0 { - utils.SendError(resp, errors.New("withdrawal amount cannot be more than 99 MYST"), http.StatusBadRequest) + amount, err := req.AmountInMYST() + if err != nil { + utils.SendError(resp, err, http.StatusBadRequest) return } diff --git a/tequilapi/endpoints/transactor_test.go b/tequilapi/endpoints/transactor_test.go index 5a1906f916..d21c2026a1 100644 --- a/tequilapi/endpoints/transactor_test.go +++ b/tequilapi/endpoints/transactor_test.go @@ -383,9 +383,9 @@ func Test_Withdrawal(t *testing.T) { t.Run(fmt.Sprintf("succeed withdrawal with fromChainID: %d, toChainID: %d", data.fromChainID, data.toChainID), func(t *testing.T) { // when body, err := json.Marshal(contract.WithdrawRequest{ - HermesID: "ignored", - ProviderID: "ignored", - Beneficiary: "ignored", + HermesID: "0xe948dae2ce1faf719ba1091d8c6664a46bab073d", + ProviderID: "0xe948dae2ce1faf719ba1091d8c6664a46bab073d", + Beneficiary: "0xe948dae2ce1faf719ba1091d8c6664a46bab073d", ToChainID: data.toChainID, FromChainID: data.fromChainID, }) @@ -418,9 +418,9 @@ func Test_Withdrawal(t *testing.T) { t.Run(fmt.Sprintf("fail withdrawal with unsuported fromChainID: %d, toChainID: %d", data.fromChainID, data.toChainID), func(t *testing.T) { // when body, err := json.Marshal(contract.WithdrawRequest{ - HermesID: "ignored", - ProviderID: "ignored", - Beneficiary: "ignored", + HermesID: "0xe948dae2ce1faf719ba1091d8c6664a46bab073d", + ProviderID: "0xe948dae2ce1faf719ba1091d8c6664a46bab073d", + Beneficiary: "0xe948dae2ce1faf719ba1091d8c6664a46bab073d", ToChainID: data.toChainID, FromChainID: data.fromChainID, })