github.com/ChainSafe/chainbridge-core@v1.4.2/chains/evm/cli/admin/withdraw.go (about) 1 package admin 2 3 import ( 4 "errors" 5 "fmt" 6 "math/big" 7 8 callsUtil "github.com/ChainSafe/chainbridge-core/chains/evm/calls" 9 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/bridge" 10 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/evmtransaction" 11 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/transactor" 12 "github.com/ChainSafe/chainbridge-core/chains/evm/cli/initialize" 13 "github.com/ChainSafe/chainbridge-core/util" 14 15 "github.com/ChainSafe/chainbridge-core/chains/evm/cli/flags" 16 "github.com/ChainSafe/chainbridge-core/chains/evm/cli/logger" 17 "github.com/ethereum/go-ethereum/common" 18 "github.com/rs/zerolog/log" 19 "github.com/spf13/cobra" 20 ) 21 22 var withdrawCmd = &cobra.Command{ 23 Use: "withdraw", 24 Short: "Withdraw tokens from a handler contract", 25 Long: "The withdraw subcommand withdrawals tokens from a handler contract", 26 PreRun: func(cmd *cobra.Command, args []string) { 27 logger.LoggerMetadata(cmd.Name(), cmd.Flags()) 28 }, 29 PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 30 return util.CallPersistentPreRun(cmd, args) 31 }, 32 RunE: func(cmd *cobra.Command, args []string) error { 33 c, err := initialize.InitializeClient(url, senderKeyPair) 34 if err != nil { 35 return err 36 } 37 t, err := initialize.InitializeTransactor(gasPrice, evmtransaction.NewTransaction, c, prepare) 38 if err != nil { 39 return err 40 } 41 return WithdrawCmd(cmd, args, bridge.NewBridgeContract(c, BridgeAddr, t)) 42 }, 43 Args: func(cmd *cobra.Command, args []string) error { 44 err := ValidateWithdrawFlags(cmd, args) 45 if err != nil { 46 return err 47 } 48 49 err = ProcessWithdrawFlags(cmd, args) 50 if err != nil { 51 return err 52 } 53 return nil 54 }, 55 } 56 57 func BindWithdrawFlags(cmd *cobra.Command) { 58 cmd.Flags().StringVar(&Amount, "amount", "", "Token amount to withdraw, use only if ERC20 token is withdrawn. If both amount and token are set an error will occur") 59 cmd.Flags().StringVar(&TokenID, "token", "", "Token ID to withdraw, use only if ERC721 token is withdrawn. If both amount and token are set an error will occur") 60 cmd.Flags().StringVar(&Bridge, "bridge", "", "Bridge contract address") 61 cmd.Flags().StringVar(&Handler, "handler", "", "Handler contract address") 62 cmd.Flags().StringVar(&Token, "token-contract", "", "ERC20 or ERC721 token contract address") 63 cmd.Flags().StringVar(&Recipient, "recipient", "", "Address to withdraw to") 64 cmd.Flags().Uint64Var(&Decimals, "decimals", 0, "ERC20 token decimals") 65 flags.MarkFlagsAsRequired(withdrawCmd, "amount", "token", "bridge", "handler", "token-contract", "recipient", "decimals") 66 } 67 68 func init() { 69 BindWithdrawFlags(withdrawCmd) 70 } 71 72 func ValidateWithdrawFlags(cmd *cobra.Command, args []string) error { 73 if !common.IsHexAddress(Bridge) { 74 return fmt.Errorf("invalid bridge address: %s", Bridge) 75 } 76 if !common.IsHexAddress(Handler) { 77 return fmt.Errorf("invalid handler address: %s", Handler) 78 } 79 if !common.IsHexAddress(Token) { 80 return fmt.Errorf("invalid token-contract address: %s", Token) 81 } 82 if !common.IsHexAddress(Recipient) { 83 return fmt.Errorf("invalid recipient address: %s", Recipient) 84 } 85 if TokenID != "" && Amount != "" { 86 return errors.New("only token or amount should be set") 87 } 88 if TokenID == "" && Amount == "" { 89 return errors.New("token or amount flag should be set") 90 } 91 return nil 92 } 93 94 func ProcessWithdrawFlags(cmd *cobra.Command, args []string) error { 95 var err error 96 97 BridgeAddr = common.HexToAddress(Bridge) 98 HandlerAddr = common.HexToAddress(Handler) 99 TokenAddr = common.HexToAddress(Token) 100 RecipientAddr = common.HexToAddress(Recipient) 101 decimals := big.NewInt(int64(Decimals)) 102 RealAmount, err = callsUtil.UserAmountToWei(Amount, decimals) 103 if err != nil { 104 return err 105 } 106 return nil 107 } 108 109 func WithdrawCmd(cmd *cobra.Command, args []string, contract *bridge.BridgeContract) error { 110 h, err := contract.Withdraw( 111 HandlerAddr, TokenAddr, RecipientAddr, RealAmount, transactor.TransactOptions{GasLimit: gasLimit}, 112 ) 113 if err != nil { 114 log.Error().Err(fmt.Errorf("admin withdrawal error: %v", err)) 115 return err 116 } 117 118 log.Info().Msgf("%s tokens were withdrawn from handler contract %s into recipient %s; tx hash: %s", Amount, Handler, Recipient, h.Hex()) 119 return nil 120 }