decred.org/dcrdex@v1.0.5/dex/networks/erc20/txdata.go (about) 1 // This code is available on the terms of the project LICENSE.md file, 2 // also available online at https://blueoakcouncil.org/license/1.0.0. 3 4 package erc20 5 6 import ( 7 "fmt" 8 "math/big" 9 10 dexeth "decred.org/dcrdex/dex/networks/eth" 11 "github.com/ethereum/go-ethereum/common" 12 ) 13 14 func parseCallData(method string, data []byte, expArgs int) ([]any, error) { 15 decoded, err := dexeth.ParseCallData(data, ERC20ABI) 16 if err != nil { 17 return nil, fmt.Errorf("unable to parse call data: %v", err) 18 } 19 if decoded.Name != method { 20 return nil, fmt.Errorf("expected %v function but got %v", method, decoded.Name) 21 } 22 if len(decoded.Args) != expArgs { 23 return nil, fmt.Errorf("wrong number of arguments. wanted %d, got %d", expArgs, len(decoded.Args)) 24 } 25 return decoded.Args, nil 26 } 27 28 // ParseTransferFromData parses the calldata used to call the transferFrom 29 // method of an ERC20 contract. 30 func ParseTransferFromData(data []byte) (sender, recipient common.Address, amount *big.Int, err error) { 31 args, err := parseCallData("transferFrom", data, 3) 32 if err != nil { 33 return common.Address{}, common.Address{}, nil, fmt.Errorf("unable to parse call data: %v", err) 34 } 35 36 sender, ok := args[0].(common.Address) 37 if !ok { 38 return common.Address{}, common.Address{}, nil, fmt.Errorf("expected first arg of type common.Address but got %T", args[0]) 39 } 40 41 recipient, ok = args[1].(common.Address) 42 if !ok { 43 return common.Address{}, common.Address{}, nil, fmt.Errorf("expected second arg of type common.Address but got %T", args[1]) 44 } 45 46 amount, ok = args[2].(*big.Int) 47 if !ok { 48 return common.Address{}, common.Address{}, nil, fmt.Errorf("expected third arg of type *big.Int but got %T", args[2]) 49 } 50 51 return sender, recipient, amount, nil 52 } 53 54 // ParseTransferData parses the calldata used to call the transfer method of an 55 // ERC20 contract. 56 func ParseTransferData(data []byte) (common.Address, *big.Int, error) { 57 args, err := parseCallData("transfer", data, 2) 58 if err != nil { 59 return common.Address{}, nil, fmt.Errorf("unable to parse call data: %v", err) 60 } 61 62 recipient, ok := args[0].(common.Address) 63 if !ok { 64 return common.Address{}, nil, fmt.Errorf("expected first arg of type common.Address but got %T", args[0]) 65 } 66 value, ok := args[1].(*big.Int) 67 if !ok { 68 return common.Address{}, nil, fmt.Errorf("expected second arg of type *big.Int but got %T", args[1]) 69 } 70 71 return recipient, value, nil 72 }