core/signer, clef: improve ui-test flow, fix errors in uint handling (#19584)
* core/signer, clef: improve ui-test flow, fix errors in uint handling for eip-712 * core/signer: add fuzzer testcases + crashfixes * signer: address review concerns, check sign in integer parsing
This commit is contained in:
		
				
					committed by
					
						 Guillaume Ballet
						Guillaume Ballet
					
				
			
			
				
	
			
			
			
						parent
						
							7a22da98b9
						
					
				
				
					commit
					17381ecc66
				
			| @@ -33,6 +33,7 @@ import ( | |||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"runtime" | 	"runtime" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
| 	"github.com/ethereum/go-ethereum/accounts" | 	"github.com/ethereum/go-ethereum/accounts" | ||||||
| 	"github.com/ethereum/go-ethereum/accounts/keystore" | 	"github.com/ethereum/go-ethereum/accounts/keystore" | ||||||
| @@ -638,6 +639,10 @@ func testExternalUI(api *core.SignerAPI) { | |||||||
| 	errs := make([]string, 0) | 	errs := make([]string, 0) | ||||||
|  |  | ||||||
| 	a := common.HexToAddress("0xdeadbeef000000000000000000000000deadbeef") | 	a := common.HexToAddress("0xdeadbeef000000000000000000000000deadbeef") | ||||||
|  | 	addErr := func(errStr string) { | ||||||
|  | 		log.Info("Test error", "error", errStr) | ||||||
|  | 		errs = append(errs, errStr) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	queryUser := func(q string) string { | 	queryUser := func(q string) string { | ||||||
| 		resp, err := api.UI.OnInputRequired(core.UserInputRequest{ | 		resp, err := api.UI.OnInputRequired(core.UserInputRequest{ | ||||||
| @@ -645,36 +650,39 @@ func testExternalUI(api *core.SignerAPI) { | |||||||
| 			Prompt: q, | 			Prompt: q, | ||||||
| 		}) | 		}) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			errs = append(errs, err.Error()) | 			addErr(err.Error()) | ||||||
| 		} | 		} | ||||||
| 		return resp.Text | 		return resp.Text | ||||||
| 	} | 	} | ||||||
| 	expectResponse := func(testcase, question, expect string) { | 	expectResponse := func(testcase, question, expect string) { | ||||||
| 		if got := queryUser(question); got != expect { | 		if got := queryUser(question); got != expect { | ||||||
| 			errs = append(errs, fmt.Sprintf("%s: got %v, expected %v", testcase, got, expect)) | 			addErr(fmt.Sprintf("%s: got %v, expected %v", testcase, got, expect)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	expectApprove := func(testcase string, err error) { | 	expectApprove := func(testcase string, err error) { | ||||||
| 		if err == nil || err == accounts.ErrUnknownAccount { | 		if err == nil || err == accounts.ErrUnknownAccount { | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
| 		errs = append(errs, fmt.Sprintf("%v: expected no error, got %v", testcase, err.Error())) | 		addErr(fmt.Sprintf("%v: expected no error, got %v", testcase, err.Error())) | ||||||
| 	} | 	} | ||||||
| 	expectDeny := func(testcase string, err error) { | 	expectDeny := func(testcase string, err error) { | ||||||
| 		if err == nil || err != core.ErrRequestDenied { | 		if err == nil || err != core.ErrRequestDenied { | ||||||
| 			errs = append(errs, fmt.Sprintf("%v: expected ErrRequestDenied, got %v", testcase, err)) | 			addErr(fmt.Sprintf("%v: expected ErrRequestDenied, got %v", testcase, err)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 	var delay = 1 * time.Second | ||||||
| 	// Test display of info and error | 	// Test display of info and error | ||||||
| 	{ | 	{ | ||||||
| 		api.UI.ShowInfo("If you see this message, enter 'yes' to next question") | 		api.UI.ShowInfo("If you see this message, enter 'yes' to next question") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		expectResponse("showinfo", "Did you see the message? [yes/no]", "yes") | 		expectResponse("showinfo", "Did you see the message? [yes/no]", "yes") | ||||||
| 		api.UI.ShowError("If you see this message, enter 'yes' to the next question") | 		api.UI.ShowError("If you see this message, enter 'yes' to the next question") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		expectResponse("showerror", "Did you see the message? [yes/no]", "yes") | 		expectResponse("showerror", "Did you see the message? [yes/no]", "yes") | ||||||
| 	} | 	} | ||||||
| 	{ // Sign data test - clique header | 	{ // Sign data test - clique header | ||||||
| 		api.UI.ShowInfo("Please approve the next request for signing a clique header") | 		api.UI.ShowInfo("Please approve the next request for signing a clique header") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		cliqueHeader := types.Header{ | 		cliqueHeader := types.Header{ | ||||||
| 			common.HexToHash("0000H45H"), | 			common.HexToHash("0000H45H"), | ||||||
| 			common.HexToHash("0000H45H"), | 			common.HexToHash("0000H45H"), | ||||||
| @@ -700,14 +708,27 @@ func testExternalUI(api *core.SignerAPI) { | |||||||
| 		_, err = api.SignData(ctx, accounts.MimetypeClique, *addr, hexutil.Encode(cliqueRlp)) | 		_, err = api.SignData(ctx, accounts.MimetypeClique, *addr, hexutil.Encode(cliqueRlp)) | ||||||
| 		expectApprove("signdata - clique header", err) | 		expectApprove("signdata - clique header", err) | ||||||
| 	} | 	} | ||||||
|  | 	{ // Sign data test - typed data | ||||||
|  | 		api.UI.ShowInfo("Please approve the next request for signing EIP-712 typed data") | ||||||
|  | 		time.Sleep(delay) | ||||||
|  | 		addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") | ||||||
|  | 		data := `{"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"Person":[{"name":"name","type":"string"},{"name":"test","type":"uint8"},{"name":"wallet","type":"address"}],"Mail":[{"name":"from","type":"Person"},{"name":"to","type":"Person"},{"name":"contents","type":"string"}]},"primaryType":"Mail","domain":{"name":"Ether Mail","version":"1","chainId":"1","verifyingContract":"0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"},"message":{"from":{"name":"Cow","test":"3","wallet":"0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"},"to":{"name":"Bob","wallet":"0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB","test":"2"},"contents":"Hello, Bob!"}}` | ||||||
|  | 		//_, err := api.SignData(ctx, accounts.MimetypeTypedData, *addr, hexutil.Encode([]byte(data))) | ||||||
|  | 		var typedData core.TypedData | ||||||
|  | 		err := json.Unmarshal([]byte(data), &typedData) | ||||||
|  | 		_, err = api.SignTypedData(ctx, *addr, typedData) | ||||||
|  | 		expectApprove("sign 712 typed data", err) | ||||||
|  | 	} | ||||||
| 	{ // Sign data test - plain text | 	{ // Sign data test - plain text | ||||||
| 		api.UI.ShowInfo("Please approve the next request for signing text") | 		api.UI.ShowInfo("Please approve the next request for signing text") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") | 		addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") | ||||||
| 		_, err := api.SignData(ctx, accounts.MimetypeTextPlain, *addr, hexutil.Encode([]byte("hello world"))) | 		_, err := api.SignData(ctx, accounts.MimetypeTextPlain, *addr, hexutil.Encode([]byte("hello world"))) | ||||||
| 		expectApprove("signdata - text", err) | 		expectApprove("signdata - text", err) | ||||||
| 	} | 	} | ||||||
| 	{ // Sign data test - plain text reject | 	{ // Sign data test - plain text reject | ||||||
| 		api.UI.ShowInfo("Please deny the next request for signing text") | 		api.UI.ShowInfo("Please deny the next request for signing text") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") | 		addr, _ := common.NewMixedcaseAddressFromString("0x0011223344556677889900112233445566778899") | ||||||
| 		_, err := api.SignData(ctx, accounts.MimetypeTextPlain, *addr, hexutil.Encode([]byte("hello world"))) | 		_, err := api.SignData(ctx, accounts.MimetypeTextPlain, *addr, hexutil.Encode([]byte("hello world"))) | ||||||
| 		expectDeny("signdata - text", err) | 		expectDeny("signdata - text", err) | ||||||
| @@ -715,6 +736,7 @@ func testExternalUI(api *core.SignerAPI) { | |||||||
| 	{ // Sign transaction | 	{ // Sign transaction | ||||||
|  |  | ||||||
| 		api.UI.ShowInfo("Please reject next transaction") | 		api.UI.ShowInfo("Please reject next transaction") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		data := hexutil.Bytes([]byte{}) | 		data := hexutil.Bytes([]byte{}) | ||||||
| 		to := common.NewMixedcaseAddress(a) | 		to := common.NewMixedcaseAddress(a) | ||||||
| 		tx := core.SendTxArgs{ | 		tx := core.SendTxArgs{ | ||||||
| @@ -733,16 +755,19 @@ func testExternalUI(api *core.SignerAPI) { | |||||||
| 	} | 	} | ||||||
| 	{ // Listing | 	{ // Listing | ||||||
| 		api.UI.ShowInfo("Please reject listing-request") | 		api.UI.ShowInfo("Please reject listing-request") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		_, err := api.List(ctx) | 		_, err := api.List(ctx) | ||||||
| 		expectDeny("list", err) | 		expectDeny("list", err) | ||||||
| 	} | 	} | ||||||
| 	{ // Import | 	{ // Import | ||||||
| 		api.UI.ShowInfo("Please reject new account-request") | 		api.UI.ShowInfo("Please reject new account-request") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		_, err := api.New(ctx) | 		_, err := api.New(ctx) | ||||||
| 		expectDeny("newaccount", err) | 		expectDeny("newaccount", err) | ||||||
| 	} | 	} | ||||||
| 	{ // Metadata | 	{ // Metadata | ||||||
| 		api.UI.ShowInfo("Please check if you see the Origin in next listing (approve or deny)") | 		api.UI.ShowInfo("Please check if you see the Origin in next listing (approve or deny)") | ||||||
|  | 		time.Sleep(delay) | ||||||
| 		api.List(context.WithValue(ctx, "Origin", "origin.com")) | 		api.List(context.WithValue(ctx, "Origin", "origin.com")) | ||||||
| 		expectResponse("metadata - origin", "Did you see origin (origin.com)? [yes/no] ", "yes") | 		expectResponse("metadata - origin", "Did you see origin (origin.com)? [yes/no] ", "yes") | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -42,6 +42,13 @@ const ( | |||||||
| // HexOrDecimal256 marshals big.Int as hex or decimal. | // HexOrDecimal256 marshals big.Int as hex or decimal. | ||||||
| type HexOrDecimal256 big.Int | type HexOrDecimal256 big.Int | ||||||
|  |  | ||||||
|  | // NewHexOrDecimal256 creates a new HexOrDecimal256 | ||||||
|  | func NewHexOrDecimal256(x int64) *HexOrDecimal256 { | ||||||
|  | 	b := big.NewInt(x) | ||||||
|  | 	h := HexOrDecimal256(*b) | ||||||
|  | 	return &h | ||||||
|  | } | ||||||
|  |  | ||||||
| // UnmarshalText implements encoding.TextUnmarshaler. | // UnmarshalText implements encoding.TextUnmarshaler. | ||||||
| func (i *HexOrDecimal256) UnmarshalText(input []byte) error { | func (i *HexOrDecimal256) UnmarshalText(input []byte) error { | ||||||
| 	bigint, ok := ParseBig256(string(input)) | 	bigint, ok := ParseBig256(string(input)) | ||||||
|   | |||||||
| @@ -482,7 +482,6 @@ func (api *SignerAPI) SignTransaction(ctx context.Context, args SendTxArgs, meth | |||||||
| 			return nil, err | 			return nil, err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	req := SignTxRequest{ | 	req := SignTxRequest{ | ||||||
| 		Transaction: args, | 		Transaction: args, | ||||||
| 		Meta:        MetadataFromContext(ctx), | 		Meta:        MetadataFromContext(ctx), | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"mime" | 	"mime" | ||||||
|  | 	"reflect" | ||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"sort" | 	"sort" | ||||||
| 	"strconv" | 	"strconv" | ||||||
| @@ -95,6 +96,9 @@ func (t *Type) typeName() string { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (t *Type) isReferenceType() bool { | func (t *Type) isReferenceType() bool { | ||||||
|  | 	if len(t.Type) == 0 { | ||||||
|  | 		return false | ||||||
|  | 	} | ||||||
| 	// Reference types must have a leading uppercase characer | 	// Reference types must have a leading uppercase characer | ||||||
| 	return unicode.IsUpper([]rune(t.Type)[0]) | 	return unicode.IsUpper([]rune(t.Type)[0]) | ||||||
| } | } | ||||||
| @@ -109,11 +113,11 @@ type TypePriority struct { | |||||||
| type TypedDataMessage = map[string]interface{} | type TypedDataMessage = map[string]interface{} | ||||||
|  |  | ||||||
| type TypedDataDomain struct { | type TypedDataDomain struct { | ||||||
| 	Name              string   `json:"name"` | 	Name              string                `json:"name"` | ||||||
| 	Version           string   `json:"version"` | 	Version           string                `json:"version"` | ||||||
| 	ChainId           *big.Int `json:"chainId"` | 	ChainId           *math.HexOrDecimal256 `json:"chainId"` | ||||||
| 	VerifyingContract string   `json:"verifyingContract"` | 	VerifyingContract string                `json:"verifyingContract"` | ||||||
| 	Salt              string   `json:"salt"` | 	Salt              string                `json:"salt"` | ||||||
| } | } | ||||||
|  |  | ||||||
| var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Z](\w*)(\[\])?$`) | var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Z](\w*)(\[\])?$`) | ||||||
| @@ -323,7 +327,10 @@ func (api *SignerAPI) SignTypedData(ctx context.Context, addr common.MixedcaseAd | |||||||
| 	} | 	} | ||||||
| 	rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) | 	rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) | ||||||
| 	sighash := crypto.Keccak256(rawData) | 	sighash := crypto.Keccak256(rawData) | ||||||
| 	message := typedData.Format() | 	message, err := typedData.Format() | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
| 	req := &SignDataRequest{ContentType: DataTyped.Mime, Rawdata: rawData, Message: message, Hash: sighash} | 	req := &SignDataRequest{ContentType: DataTyped.Mime, Rawdata: rawData, Message: message, Hash: sighash} | ||||||
| 	signature, err := api.sign(addr, req, true) | 	signature, err := api.sign(addr, req, true) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @@ -377,9 +384,11 @@ func (typedData *TypedData) Dependencies(primaryType string, found []string) []s | |||||||
| func (typedData *TypedData) EncodeType(primaryType string) hexutil.Bytes { | func (typedData *TypedData) EncodeType(primaryType string) hexutil.Bytes { | ||||||
| 	// Get dependencies primary first, then alphabetical | 	// Get dependencies primary first, then alphabetical | ||||||
| 	deps := typedData.Dependencies(primaryType, []string{}) | 	deps := typedData.Dependencies(primaryType, []string{}) | ||||||
| 	slicedDeps := deps[1:] | 	if len(deps) > 0 { | ||||||
| 	sort.Strings(slicedDeps) | 		slicedDeps := deps[1:] | ||||||
| 	deps = append([]string{primaryType}, slicedDeps...) | 		sort.Strings(slicedDeps) | ||||||
|  | 		deps = append([]string{primaryType}, slicedDeps...) | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// Format as a string with fields | 	// Format as a string with fields | ||||||
| 	var buffer bytes.Buffer | 	var buffer bytes.Buffer | ||||||
| @@ -476,10 +485,60 @@ func (typedData *TypedData) EncodeData(primaryType string, data map[string]inter | |||||||
| 	return buffer.Bytes(), nil | 	return buffer.Bytes(), nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func parseInteger(encType string, encValue interface{}) (*big.Int, error) { | ||||||
|  | 	var ( | ||||||
|  | 		length = 0 | ||||||
|  | 		signed = strings.HasPrefix(encType, "int") | ||||||
|  | 		b      *big.Int | ||||||
|  | 	) | ||||||
|  | 	if encType == "int" || encType == "uint" { | ||||||
|  | 		length = 256 | ||||||
|  | 	} else { | ||||||
|  | 		lengthStr := "" | ||||||
|  | 		if strings.HasPrefix(encType, "uint") { | ||||||
|  | 			lengthStr = strings.TrimPrefix(encType, "uint") | ||||||
|  | 		} else { | ||||||
|  | 			lengthStr = strings.TrimPrefix(encType, "int") | ||||||
|  | 		} | ||||||
|  | 		atoiSize, err := strconv.Atoi(lengthStr) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, fmt.Errorf("invalid size on integer: %v", lengthStr) | ||||||
|  | 		} | ||||||
|  | 		length = atoiSize | ||||||
|  | 	} | ||||||
|  | 	switch v := encValue.(type) { | ||||||
|  | 	case *math.HexOrDecimal256: | ||||||
|  | 		b = (*big.Int)(v) | ||||||
|  | 	case string: | ||||||
|  | 		var hexIntValue math.HexOrDecimal256 | ||||||
|  | 		if err := hexIntValue.UnmarshalText([]byte(v)); err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		b = (*big.Int)(&hexIntValue) | ||||||
|  | 	case float64: | ||||||
|  | 		// JSON parses non-strings as float64. Fail if we cannot | ||||||
|  | 		// convert it losslessly | ||||||
|  | 		if float64(int64(v)) == v { | ||||||
|  | 			b = big.NewInt(int64(v)) | ||||||
|  | 		} else { | ||||||
|  | 			return nil, fmt.Errorf("invalid float value %v for type %v", v, encType) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	if b == nil { | ||||||
|  | 		return nil, fmt.Errorf("invalid integer value %v/%v for type %v", encValue, reflect.TypeOf(encValue), encType) | ||||||
|  | 	} | ||||||
|  | 	if b.BitLen() > length { | ||||||
|  | 		return nil, fmt.Errorf("integer larger than '%v'", encType) | ||||||
|  | 	} | ||||||
|  | 	if !signed && b.Sign() == -1 { | ||||||
|  | 		return nil, fmt.Errorf("invalid negative value for unsigned type %v", encType) | ||||||
|  | 	} | ||||||
|  | 	return b, nil | ||||||
|  | } | ||||||
|  |  | ||||||
| // EncodePrimitiveValue deals with the primitive values found | // EncodePrimitiveValue deals with the primitive values found | ||||||
| // while searching through the typed data | // while searching through the typed data | ||||||
| func (typedData *TypedData) EncodePrimitiveValue(encType string, encValue interface{}, depth int) ([]byte, error) { | func (typedData *TypedData) EncodePrimitiveValue(encType string, encValue interface{}, depth int) ([]byte, error) { | ||||||
|  |  | ||||||
| 	switch encType { | 	switch encType { | ||||||
| 	case "address": | 	case "address": | ||||||
| 		stringValue, ok := encValue.(string) | 		stringValue, ok := encValue.(string) | ||||||
| @@ -527,30 +586,11 @@ func (typedData *TypedData) EncodePrimitiveValue(encType string, encValue interf | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	if strings.HasPrefix(encType, "int") || strings.HasPrefix(encType, "uint") { | 	if strings.HasPrefix(encType, "int") || strings.HasPrefix(encType, "uint") { | ||||||
| 		length := 0 | 		b, err := parseInteger(encType, encValue) | ||||||
| 		if encType == "int" || encType == "uint" { | 		if err != nil { | ||||||
| 			length = 256 | 			return nil, err | ||||||
| 		} else { |  | ||||||
| 			lengthStr := "" |  | ||||||
| 			if strings.HasPrefix(encType, "uint") { |  | ||||||
| 				lengthStr = strings.TrimPrefix(encType, "uint") |  | ||||||
| 			} else { |  | ||||||
| 				lengthStr = strings.TrimPrefix(encType, "int") |  | ||||||
| 			} |  | ||||||
| 			atoiSize, err := strconv.Atoi(lengthStr) |  | ||||||
| 			if err != nil { |  | ||||||
| 				return nil, fmt.Errorf("invalid size on integer: %v", lengthStr) |  | ||||||
| 			} |  | ||||||
| 			length = atoiSize |  | ||||||
| 		} | 		} | ||||||
| 		bigIntValue, ok := encValue.(*big.Int) | 		return abi.U256(b), nil | ||||||
| 		if bigIntValue.BitLen() > length { |  | ||||||
| 			return nil, fmt.Errorf("integer larger than '%v'", encType) |  | ||||||
| 		} |  | ||||||
| 		if !ok { |  | ||||||
| 			return nil, dataMismatchError(encType, encValue) |  | ||||||
| 		} |  | ||||||
| 		return abi.U256(bigIntValue), nil |  | ||||||
| 	} | 	} | ||||||
| 	return nil, fmt.Errorf("unrecognized type '%s'", encType) | 	return nil, fmt.Errorf("unrecognized type '%s'", encType) | ||||||
|  |  | ||||||
| @@ -649,35 +689,32 @@ func (typedData *TypedData) Map() map[string]interface{} { | |||||||
| 	return dataMap | 	return dataMap | ||||||
| } | } | ||||||
|  |  | ||||||
| // PrettyPrint generates a nice output to help the users |  | ||||||
| // of clef present data in their apps |  | ||||||
| func (typedData *TypedData) PrettyPrint() string { |  | ||||||
| 	output := bytes.Buffer{} |  | ||||||
| 	formatted := typedData.Format() |  | ||||||
| 	for _, item := range formatted { |  | ||||||
| 		output.WriteString(fmt.Sprintf("%v\n", item.Pprint(0))) |  | ||||||
| 	} |  | ||||||
| 	return output.String() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Format returns a representation of typedData, which can be easily displayed by a user-interface | // Format returns a representation of typedData, which can be easily displayed by a user-interface | ||||||
| // without in-depth knowledge about 712 rules | // without in-depth knowledge about 712 rules | ||||||
| func (typedData *TypedData) Format() []*NameValueType { | func (typedData *TypedData) Format() ([]*NameValueType, error) { | ||||||
|  | 	domain, err := typedData.formatData("EIP712Domain", typedData.Domain.Map()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	ptype, err := typedData.formatData(typedData.PrimaryType, typedData.Message) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
| 	var nvts []*NameValueType | 	var nvts []*NameValueType | ||||||
| 	nvts = append(nvts, &NameValueType{ | 	nvts = append(nvts, &NameValueType{ | ||||||
| 		Name:  "EIP712Domain", | 		Name:  "EIP712Domain", | ||||||
| 		Value: typedData.formatData("EIP712Domain", typedData.Domain.Map()), | 		Value: domain, | ||||||
| 		Typ:   "domain", | 		Typ:   "domain", | ||||||
| 	}) | 	}) | ||||||
| 	nvts = append(nvts, &NameValueType{ | 	nvts = append(nvts, &NameValueType{ | ||||||
| 		Name:  typedData.PrimaryType, | 		Name:  typedData.PrimaryType, | ||||||
| 		Value: typedData.formatData(typedData.PrimaryType, typedData.Message), | 		Value: ptype, | ||||||
| 		Typ:   "primary type", | 		Typ:   "primary type", | ||||||
| 	}) | 	}) | ||||||
| 	return nvts | 	return nvts, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (typedData *TypedData) formatData(primaryType string, data map[string]interface{}) []*NameValueType { | func (typedData *TypedData) formatData(primaryType string, data map[string]interface{}) ([]*NameValueType, error) { | ||||||
| 	var output []*NameValueType | 	var output []*NameValueType | ||||||
|  |  | ||||||
| 	// Add field contents. Structs and arrays have special handlers. | 	// Add field contents. Structs and arrays have special handlers. | ||||||
| @@ -694,44 +731,70 @@ func (typedData *TypedData) formatData(primaryType string, data map[string]inter | |||||||
| 			for _, v := range arrayValue { | 			for _, v := range arrayValue { | ||||||
| 				if typedData.Types[parsedType] != nil { | 				if typedData.Types[parsedType] != nil { | ||||||
| 					mapValue, _ := v.(map[string]interface{}) | 					mapValue, _ := v.(map[string]interface{}) | ||||||
| 					mapOutput := typedData.formatData(parsedType, mapValue) | 					mapOutput, err := typedData.formatData(parsedType, mapValue) | ||||||
|  | 					if err != nil { | ||||||
|  | 						return nil, err | ||||||
|  | 					} | ||||||
| 					item.Value = mapOutput | 					item.Value = mapOutput | ||||||
| 				} else { | 				} else { | ||||||
| 					primitiveOutput := formatPrimitiveValue(field.Type, encValue) | 					primitiveOutput, err := formatPrimitiveValue(field.Type, encValue) | ||||||
|  | 					if err != nil { | ||||||
|  | 						return nil, err | ||||||
|  | 					} | ||||||
| 					item.Value = primitiveOutput | 					item.Value = primitiveOutput | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} else if typedData.Types[field.Type] != nil { | 		} else if typedData.Types[field.Type] != nil { | ||||||
| 			mapValue, _ := encValue.(map[string]interface{}) | 			if mapValue, ok := encValue.(map[string]interface{}); ok { | ||||||
| 			mapOutput := typedData.formatData(field.Type, mapValue) | 				mapOutput, err := typedData.formatData(field.Type, mapValue) | ||||||
| 			item.Value = mapOutput | 				if err != nil { | ||||||
|  | 					return nil, err | ||||||
|  | 				} | ||||||
|  | 				item.Value = mapOutput | ||||||
|  | 			} else { | ||||||
|  | 				item.Value = "<nil>" | ||||||
|  | 			} | ||||||
| 		} else { | 		} else { | ||||||
| 			primitiveOutput := formatPrimitiveValue(field.Type, encValue) | 			primitiveOutput, err := formatPrimitiveValue(field.Type, encValue) | ||||||
|  | 			if err != nil { | ||||||
|  | 				return nil, err | ||||||
|  | 			} | ||||||
| 			item.Value = primitiveOutput | 			item.Value = primitiveOutput | ||||||
| 		} | 		} | ||||||
| 		output = append(output, item) | 		output = append(output, item) | ||||||
| 	} | 	} | ||||||
| 	return output | 	return output, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func formatPrimitiveValue(encType string, encValue interface{}) string { | func formatPrimitiveValue(encType string, encValue interface{}) (string, error) { | ||||||
| 	switch encType { | 	switch encType { | ||||||
| 	case "address": | 	case "address": | ||||||
| 		stringValue, _ := encValue.(string) | 		if stringValue, ok := encValue.(string); !ok { | ||||||
| 		return common.HexToAddress(stringValue).String() | 			return "", fmt.Errorf("could not format value %v as address", encValue) | ||||||
|  | 		} else { | ||||||
|  | 			return common.HexToAddress(stringValue).String(), nil | ||||||
|  | 		} | ||||||
| 	case "bool": | 	case "bool": | ||||||
| 		boolValue, _ := encValue.(bool) | 		if boolValue, ok := encValue.(bool); !ok { | ||||||
| 		return fmt.Sprintf("%t", boolValue) | 			return "", fmt.Errorf("could not format value %v as bool", encValue) | ||||||
|  | 		} else { | ||||||
|  | 			return fmt.Sprintf("%t", boolValue), nil | ||||||
|  | 		} | ||||||
| 	case "bytes", "string": | 	case "bytes", "string": | ||||||
| 		return fmt.Sprintf("%s", encValue) | 		return fmt.Sprintf("%s", encValue), nil | ||||||
| 	} | 	} | ||||||
| 	if strings.HasPrefix(encType, "bytes") { | 	if strings.HasPrefix(encType, "bytes") { | ||||||
| 		return fmt.Sprintf("%s", encValue) | 		return fmt.Sprintf("%s", encValue), nil | ||||||
| 	} else if strings.HasPrefix(encType, "uint") || strings.HasPrefix(encType, "int") { |  | ||||||
| 		bigIntValue, _ := encValue.(*big.Int) |  | ||||||
| 		return fmt.Sprintf("%d (0x%x)", bigIntValue, bigIntValue) |  | ||||||
| 	} | 	} | ||||||
| 	return "NA" | 	if strings.HasPrefix(encType, "uint") || strings.HasPrefix(encType, "int") { | ||||||
|  | 		if b, err := parseInteger(encType, encValue); err != nil { | ||||||
|  | 			return "", err | ||||||
|  | 		} else { | ||||||
|  | 			return fmt.Sprintf("%d (0x%x)", b, b), nil | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return "", fmt.Errorf("unhandled type %v", encType) | ||||||
| } | } | ||||||
|  |  | ||||||
| // NameValueType is a very simple struct with Name, Value and Type. It's meant for simple | // NameValueType is a very simple struct with Name, Value and Type. It's meant for simple | ||||||
| @@ -762,12 +825,21 @@ func (nvt *NameValueType) Pprint(depth int) string { | |||||||
| // Validate checks if the types object is conformant to the specs | // Validate checks if the types object is conformant to the specs | ||||||
| func (t Types) validate() error { | func (t Types) validate() error { | ||||||
| 	for typeKey, typeArr := range t { | 	for typeKey, typeArr := range t { | ||||||
| 		for _, typeObj := range typeArr { | 		if len(typeKey) == 0 { | ||||||
|  | 			return fmt.Errorf("empty type key") | ||||||
|  | 		} | ||||||
|  | 		for i, typeObj := range typeArr { | ||||||
|  | 			if len(typeObj.Type) == 0 { | ||||||
|  | 				return fmt.Errorf("type %v:%d: empty Type", typeKey, i) | ||||||
|  | 			} | ||||||
|  | 			if len(typeObj.Name) == 0 { | ||||||
|  | 				return fmt.Errorf("type %v:%d: empty Name", typeKey, i) | ||||||
|  | 			} | ||||||
| 			if typeKey == typeObj.Type { | 			if typeKey == typeObj.Type { | ||||||
| 				return fmt.Errorf("type '%s' cannot reference itself", typeObj.Type) | 				return fmt.Errorf("type '%s' cannot reference itself", typeObj.Type) | ||||||
| 			} | 			} | ||||||
| 			if typeObj.isReferenceType() { | 			if typeObj.isReferenceType() { | ||||||
| 				if _, exist := t[typeObj.Type]; !exist { | 				if _, exist := t[typeObj.typeName()]; !exist { | ||||||
| 					return fmt.Errorf("reference type '%s' is undefined", typeObj.Type) | 					return fmt.Errorf("reference type '%s' is undefined", typeObj.Type) | ||||||
| 				} | 				} | ||||||
| 				if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) { | 				if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) { | ||||||
| @@ -895,7 +967,7 @@ func isPrimitiveTypeValid(primitiveType string) bool { | |||||||
| // validate checks if the given domain is valid, i.e. contains at least | // validate checks if the given domain is valid, i.e. contains at least | ||||||
| // the minimum viable keys and values | // the minimum viable keys and values | ||||||
| func (domain *TypedDataDomain) validate() error { | func (domain *TypedDataDomain) validate() error { | ||||||
| 	if domain.ChainId == big.NewInt(0) { | 	if domain.ChainId == nil { | ||||||
| 		return errors.New("chainId must be specified according to EIP-155") | 		return errors.New("chainId must be specified according to EIP-155") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										51
									
								
								signer/core/signed_data_internal_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								signer/core/signed_data_internal_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | |||||||
|  | // Copyright 2019 The go-ethereum Authors | ||||||
|  | // This file is part of go-ethereum. | ||||||
|  | // | ||||||
|  | // go-ethereum is free software: you can redistribute it and/or modify | ||||||
|  | // it under the terms of the GNU General Public License as published by | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or | ||||||
|  | // (at your option) any later version. | ||||||
|  | // | ||||||
|  | // go-ethereum is distributed in the hope that it will be useful, | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||||
|  | // GNU General Public License for more details. | ||||||
|  | // | ||||||
|  | // You should have received a copy of the GNU General Public License | ||||||
|  | // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | // | ||||||
|  | package core | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"math/big" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestParseInteger(t *testing.T) { | ||||||
|  | 	for i, tt := range []struct { | ||||||
|  | 		t   string | ||||||
|  | 		v   interface{} | ||||||
|  | 		exp *big.Int | ||||||
|  | 	}{ | ||||||
|  | 		{"uint32", "-123", nil}, | ||||||
|  | 		{"int32", "-123", big.NewInt(-123)}, | ||||||
|  | 		{"uint32", "0xff", big.NewInt(0xff)}, | ||||||
|  | 		{"int8", "0xffff", nil}, | ||||||
|  | 	} { | ||||||
|  | 		res, err := parseInteger(tt.t, tt.v) | ||||||
|  | 		if tt.exp == nil && res == nil { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		if tt.exp == nil && res != nil { | ||||||
|  | 			t.Errorf("test %d, got %v, expected nil", i, res) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		if tt.exp != nil && res == nil { | ||||||
|  | 			t.Errorf("test %d, got '%v', expected %v", i, err, tt.exp) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		if tt.exp.Cmp(res) != 0 { | ||||||
|  | 			t.Errorf("test %d, got %v expected %v", i, res, tt.exp) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -20,12 +20,16 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"math/big" | 	"io/ioutil" | ||||||
|  | 	"path" | ||||||
|  | 	"strings" | ||||||
| 	"testing" | 	"testing" | ||||||
|  |  | ||||||
| 	"github.com/ethereum/go-ethereum/accounts/keystore" | 	"github.com/ethereum/go-ethereum/accounts/keystore" | ||||||
| 	"github.com/ethereum/go-ethereum/common" | 	"github.com/ethereum/go-ethereum/common" | ||||||
| 	"github.com/ethereum/go-ethereum/common/hexutil" | 	"github.com/ethereum/go-ethereum/common/hexutil" | ||||||
|  | 	"github.com/ethereum/go-ethereum/common/math" | ||||||
|  | 	"github.com/ethereum/go-ethereum/crypto" | ||||||
| 	"github.com/ethereum/go-ethereum/signer/core" | 	"github.com/ethereum/go-ethereum/signer/core" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @@ -128,7 +132,7 @@ var jsonTypedData = ` | |||||||
|       "domain": { |       "domain": { | ||||||
|         "name": "Ether Mail", |         "name": "Ether Mail", | ||||||
|         "version": "1", |         "version": "1", | ||||||
|         "chainId": 1, |         "chainId": "1", | ||||||
|         "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" |         "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|       }, |       }, | ||||||
|       "message": { |       "message": { | ||||||
| @@ -151,7 +155,7 @@ const primaryType = "Mail" | |||||||
| var domainStandard = core.TypedDataDomain{ | var domainStandard = core.TypedDataDomain{ | ||||||
| 	"Ether Mail", | 	"Ether Mail", | ||||||
| 	"1", | 	"1", | ||||||
| 	big.NewInt(1), | 	math.NewHexOrDecimal256(1), | ||||||
| 	"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", | 	"0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", | ||||||
| 	"", | 	"", | ||||||
| } | } | ||||||
| @@ -241,7 +245,6 @@ func TestDomainChainId(t *testing.T) { | |||||||
| 	if _, ok := withoutChainID.Domain.Map()["chainId"]; ok { | 	if _, ok := withoutChainID.Domain.Map()["chainId"]; ok { | ||||||
| 		t.Errorf("Expected the chainId key to not be present in the domain map") | 		t.Errorf("Expected the chainId key to not be present in the domain map") | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	withChainID := core.TypedData{ | 	withChainID := core.TypedData{ | ||||||
| 		Types: core.Types{ | 		Types: core.Types{ | ||||||
| 			"EIP712Domain": []core.Type{ | 			"EIP712Domain": []core.Type{ | ||||||
| @@ -251,7 +254,7 @@ func TestDomainChainId(t *testing.T) { | |||||||
| 		}, | 		}, | ||||||
| 		Domain: core.TypedDataDomain{ | 		Domain: core.TypedDataDomain{ | ||||||
| 			Name:    "test", | 			Name:    "test", | ||||||
| 			ChainId: big.NewInt(1), | 			ChainId: math.NewHexOrDecimal256(1), | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -310,495 +313,13 @@ func TestEncodeData(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| func TestMalformedDomainkeys(t *testing.T) { |  | ||||||
| 	// Verifies that malformed domain keys are properly caught: |  | ||||||
| 	//{ |  | ||||||
| 	//	"name": "Ether Mail", |  | ||||||
| 	//	"version": "1", |  | ||||||
| 	//	"chainId": 1, |  | ||||||
| 	//	"vxerifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" |  | ||||||
| 	//} |  | ||||||
| 	jsonTypedData := ` |  | ||||||
|     { |  | ||||||
|       "types": { |  | ||||||
|         "EIP712Domain": [ |  | ||||||
|           { |  | ||||||
|             "name": "name", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "version", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "chainId", |  | ||||||
|             "type": "uint256" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "verifyingContract", |  | ||||||
|             "type": "address" |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         "Person": [ |  | ||||||
|           { |  | ||||||
|             "name": "name", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "wallet", |  | ||||||
|             "type": "address" |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         "Mail": [ |  | ||||||
|           { |  | ||||||
|             "name": "from", |  | ||||||
|             "type": "Person" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "to", |  | ||||||
|             "type": "Person" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "contents", |  | ||||||
|             "type": "string" |  | ||||||
|           } |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|       "primaryType": "Mail", |  | ||||||
|       "domain": { |  | ||||||
|         "name": "Ether Mail", |  | ||||||
|         "version": "1", |  | ||||||
|         "chainId": 1, |  | ||||||
|         "vxerifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" |  | ||||||
|       }, |  | ||||||
|       "message": { |  | ||||||
|         "from": { |  | ||||||
|           "name": "Cow", |  | ||||||
|           "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" |  | ||||||
|         }, |  | ||||||
|         "to": { |  | ||||||
|           "name": "Bob", |  | ||||||
|           "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" |  | ||||||
|         }, |  | ||||||
|         "contents": "Hello, Bob!" |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| ` |  | ||||||
| 	var malformedDomainTypedData core.TypedData |  | ||||||
| 	err := json.Unmarshal([]byte(jsonTypedData), &malformedDomainTypedData) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("unmarshalling failed '%v'", err) |  | ||||||
| 	} |  | ||||||
| 	_, err = malformedDomainTypedData.HashStruct("EIP712Domain", malformedDomainTypedData.Domain.Map()) |  | ||||||
| 	if err == nil || err.Error() != "provided data '<nil>' doesn't match type 'address'" { |  | ||||||
| 		t.Errorf("Expected `provided data '<nil>' doesn't match type 'address'`, got '%v'", err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestMalformedTypesAndExtradata(t *testing.T) { |  | ||||||
| 	// Verifies several quirks |  | ||||||
| 	// 1. Using dynamic types and only validating the prefix: |  | ||||||
| 	//{ |  | ||||||
| 	//	"name": "chainId", |  | ||||||
| 	//	"type": "uint256 ... and now for something completely different" |  | ||||||
| 	//} |  | ||||||
| 	// 2. Extra data in message: |  | ||||||
| 	//{ |  | ||||||
| 	//  "blahonga": "zonk bonk" |  | ||||||
| 	//} |  | ||||||
| 	jsonTypedData := ` |  | ||||||
|     { |  | ||||||
|       "types": { |  | ||||||
|         "EIP712Domain": [ |  | ||||||
|           { |  | ||||||
|             "name": "name", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "version", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "chainId", |  | ||||||
|             "type": "uint256 ... and now for something completely different" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "verifyingContract", |  | ||||||
|             "type": "address" |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         "Person": [ |  | ||||||
|           { |  | ||||||
|             "name": "name", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "wallet", |  | ||||||
|             "type": "address" |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         "Mail": [ |  | ||||||
|           { |  | ||||||
|             "name": "from", |  | ||||||
|             "type": "Person" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "to", |  | ||||||
|             "type": "Person" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "contents", |  | ||||||
|             "type": "string" |  | ||||||
|           } |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|       "primaryType": "Mail", |  | ||||||
|       "domain": { |  | ||||||
|         "name": "Ether Mail", |  | ||||||
|         "version": "1", |  | ||||||
|         "chainId": 1, |  | ||||||
|         "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" |  | ||||||
|       }, |  | ||||||
|       "message": { |  | ||||||
|         "from": { |  | ||||||
|           "name": "Cow", |  | ||||||
|           "wallet": "0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" |  | ||||||
|         }, |  | ||||||
|         "to": { |  | ||||||
|           "name": "Bob", |  | ||||||
|           "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" |  | ||||||
|         }, |  | ||||||
|         "contents": "Hello, Bob!" |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| ` |  | ||||||
| 	var malformedTypedData core.TypedData |  | ||||||
| 	err := json.Unmarshal([]byte(jsonTypedData), &malformedTypedData) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("unmarshalling failed '%v'", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	malformedTypedData.Types["EIP712Domain"][2].Type = "uint256" |  | ||||||
| 	malformedTypedData.Message["blahonga"] = "zonk bonk" |  | ||||||
| 	_, err = malformedTypedData.HashStruct(malformedTypedData.PrimaryType, malformedTypedData.Message) |  | ||||||
| 	if err == nil || err.Error() != "there is extra data provided in the message" { |  | ||||||
| 		t.Errorf("Expected `there is extra data provided in the message`, got '%v'", err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestTypeMismatch(t *testing.T) { |  | ||||||
| 	// Verifies that: |  | ||||||
| 	// 1. Mismatches between the given type and data, i.e. `Person` and |  | ||||||
| 	// 		the data item is a string, are properly caught: |  | ||||||
| 	//{ |  | ||||||
| 	//	"name": "contents", |  | ||||||
| 	//	"type": "Person" |  | ||||||
| 	//}, |  | ||||||
| 	//{ |  | ||||||
| 	//	"contents": "Hello, Bob!" <-- string not "Person" |  | ||||||
| 	//} |  | ||||||
| 	// 2. Nonexistent types are properly caught: |  | ||||||
| 	//{ |  | ||||||
| 	//	"name": "contents", |  | ||||||
| 	//	"type": "Blahonga" |  | ||||||
| 	//} |  | ||||||
| 	jsonTypedData := ` |  | ||||||
|     { |  | ||||||
|       "types": { |  | ||||||
|         "EIP712Domain": [ |  | ||||||
|           { |  | ||||||
|             "name": "name", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "version", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "chainId", |  | ||||||
|             "type": "uint256" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "verifyingContract", |  | ||||||
|             "type": "address" |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         "Person": [ |  | ||||||
|           { |  | ||||||
|             "name": "name", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "wallet", |  | ||||||
|             "type": "address" |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         "Mail": [ |  | ||||||
|           { |  | ||||||
|             "name": "from", |  | ||||||
|             "type": "Person" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "to", |  | ||||||
|             "type": "Person" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "contents", |  | ||||||
|             "type": "Person" |  | ||||||
|           } |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|       "primaryType": "Mail", |  | ||||||
|       "domain": { |  | ||||||
|         "name": "Ether Mail", |  | ||||||
|         "version": "1", |  | ||||||
|         "chainId": 1, |  | ||||||
|         "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" |  | ||||||
|       }, |  | ||||||
|       "message": { |  | ||||||
|         "from": { |  | ||||||
|           "name": "Cow", |  | ||||||
|           "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" |  | ||||||
|         }, |  | ||||||
|         "to": { |  | ||||||
|           "name": "Bob", |  | ||||||
|           "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" |  | ||||||
|         }, |  | ||||||
|         "contents": "Hello, Bob!" |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
| ` |  | ||||||
| 	var mismatchTypedData core.TypedData |  | ||||||
| 	err := json.Unmarshal([]byte(jsonTypedData), &mismatchTypedData) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("unmarshalling failed '%v'", err) |  | ||||||
| 	} |  | ||||||
| 	_, err = mismatchTypedData.HashStruct(mismatchTypedData.PrimaryType, mismatchTypedData.Message) |  | ||||||
| 	if err.Error() != "provided data 'Hello, Bob!' doesn't match type 'Person'" { |  | ||||||
| 		t.Errorf("Expected `provided data 'Hello, Bob!' doesn't match type 'Person'`, got '%v'", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	mismatchTypedData.Types["Mail"][2].Type = "Blahonga" |  | ||||||
| 	_, err = mismatchTypedData.HashStruct(mismatchTypedData.PrimaryType, mismatchTypedData.Message) |  | ||||||
| 	if err == nil || err.Error() != "reference type 'Blahonga' is undefined" { |  | ||||||
| 		t.Fatalf("Expected `reference type 'Blahonga' is undefined`, got '%v'", err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestTypeOverflow(t *testing.T) { |  | ||||||
| 	// Verifies data that doesn't fit into it: |  | ||||||
| 	//{ |  | ||||||
| 	//	"test": 65536 <-- test defined as uint8 |  | ||||||
| 	//} |  | ||||||
| 	var overflowTypedData core.TypedData |  | ||||||
| 	err := json.Unmarshal([]byte(jsonTypedData), &overflowTypedData) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("unmarshalling failed '%v'", err) |  | ||||||
| 	} |  | ||||||
| 	// Set test to something outside uint8 |  | ||||||
| 	(overflowTypedData.Message["from"]).(map[string]interface{})["test"] = big.NewInt(65536) |  | ||||||
|  |  | ||||||
| 	_, err = overflowTypedData.HashStruct(overflowTypedData.PrimaryType, overflowTypedData.Message) |  | ||||||
| 	if err == nil || err.Error() != "integer larger than 'uint8'" { |  | ||||||
| 		t.Fatalf("Expected `integer larger than 'uint8'`, got '%v'", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	(overflowTypedData.Message["from"]).(map[string]interface{})["test"] = big.NewInt(3) |  | ||||||
| 	(overflowTypedData.Message["to"]).(map[string]interface{})["test"] = big.NewInt(4) |  | ||||||
|  |  | ||||||
| 	_, err = overflowTypedData.HashStruct(overflowTypedData.PrimaryType, overflowTypedData.Message) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Expected no err, got '%v'", err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestArray(t *testing.T) { |  | ||||||
| 	// Makes sure that arrays work fine |  | ||||||
| 	//{ |  | ||||||
| 	//	"type": "address[]" |  | ||||||
| 	//}, |  | ||||||
| 	//{ |  | ||||||
| 	//	"type": "string[]" |  | ||||||
| 	//}, |  | ||||||
| 	//{ |  | ||||||
| 	//	"type": "uint16[]", |  | ||||||
| 	//} |  | ||||||
|  |  | ||||||
| 	jsonTypedData := ` |  | ||||||
| 		{ |  | ||||||
| 	      "types": { |  | ||||||
| 	        "EIP712Domain": [ |  | ||||||
| 	          { |  | ||||||
| 	            "name": "name", |  | ||||||
| 	            "type": "string" |  | ||||||
| 	          }, |  | ||||||
| 	          { |  | ||||||
| 	            "name": "version", |  | ||||||
| 	            "type": "string" |  | ||||||
| 	          }, |  | ||||||
| 	          { |  | ||||||
| 	            "name": "chainId", |  | ||||||
| 	            "type": "uint256" |  | ||||||
| 	          }, |  | ||||||
| 	          { |  | ||||||
| 	            "name": "verifyingContract", |  | ||||||
| 	            "type": "address" |  | ||||||
| 	          } |  | ||||||
| 	        ], |  | ||||||
| 	        "Foo": [ |  | ||||||
| 	          { |  | ||||||
| 	            "name": "bar", |  | ||||||
| 	            "type": "address[]" |  | ||||||
| 	          } |  | ||||||
| 	        ] |  | ||||||
| 	      }, |  | ||||||
| 	      "primaryType": "Foo", |  | ||||||
| 	      "domain": { |  | ||||||
| 	        "name": "Lorem", |  | ||||||
| 	        "version": "1", |  | ||||||
| 	        "chainId": 1, |  | ||||||
| 	        "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" |  | ||||||
| 	      }, |  | ||||||
| 	      "message": { |  | ||||||
| 	        "bar": [ |  | ||||||
| 	        	"0x0000000000000000000000000000000000000001", |  | ||||||
| 	        	"0x0000000000000000000000000000000000000002", |  | ||||||
| 	        	"0x0000000000000000000000000000000000000003" |  | ||||||
|         	] |  | ||||||
| 	      } |  | ||||||
| 	    } |  | ||||||
| 	` |  | ||||||
| 	var arrayTypedData core.TypedData |  | ||||||
| 	err := json.Unmarshal([]byte(jsonTypedData), &arrayTypedData) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("unmarshalling failed '%v'", err) |  | ||||||
| 	} |  | ||||||
| 	_, err = arrayTypedData.HashStruct(arrayTypedData.PrimaryType, arrayTypedData.Message) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Expected no err, got '%v'", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Change array to string |  | ||||||
| 	arrayTypedData.Types["Foo"][0].Type = "string[]" |  | ||||||
| 	arrayTypedData.Message["bar"] = []interface{}{ |  | ||||||
| 		"lorem", |  | ||||||
| 		"ipsum", |  | ||||||
| 		"dolores", |  | ||||||
| 	} |  | ||||||
| 	_, err = arrayTypedData.HashStruct(arrayTypedData.PrimaryType, arrayTypedData.Message) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Expected no err, got '%v'", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Change array to uint |  | ||||||
| 	arrayTypedData.Types["Foo"][0].Type = "uint[]" |  | ||||||
| 	arrayTypedData.Message["bar"] = []interface{}{ |  | ||||||
| 		big.NewInt(1955), |  | ||||||
| 		big.NewInt(108), |  | ||||||
| 		big.NewInt(44010), |  | ||||||
| 	} |  | ||||||
| 	_, err = arrayTypedData.HashStruct(arrayTypedData.PrimaryType, arrayTypedData.Message) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("Expected no err, got '%v'", err) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	// Should not work with fixed-size arrays |  | ||||||
| 	arrayTypedData.Types["Foo"][0].Type = "uint[3]" |  | ||||||
| 	_, err = arrayTypedData.HashStruct(arrayTypedData.PrimaryType, arrayTypedData.Message) |  | ||||||
| 	if err == nil || err.Error() != "unknown type 'uint[3]'" { |  | ||||||
| 		t.Fatalf("Expected `unknown type 'uint[3]'`, got '%v'", err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestCustomTypeAsArray(t *testing.T) { |  | ||||||
| 	var jsonTypedData = ` |  | ||||||
|     { |  | ||||||
|       "types": { |  | ||||||
|         "EIP712Domain": [ |  | ||||||
|           { |  | ||||||
|             "name": "name", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
| 			"name": "version", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
|             "name": "chainId", |  | ||||||
|             "type": "uint256" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
| 			"name": "verifyingContract", |  | ||||||
|             "type": "address" |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         "Person": [ |  | ||||||
|           { |  | ||||||
| 			"name": "name", |  | ||||||
|             "type": "string" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
| 			"name": "wallet", |  | ||||||
|             "type": "address" |  | ||||||
|           } |  | ||||||
|         ], |  | ||||||
|         "Person[]": [ |  | ||||||
|           { |  | ||||||
| 			"name": "baz", |  | ||||||
|             "type": "string" |  | ||||||
|           } |  | ||||||
| 		], |  | ||||||
|         "Mail": [ |  | ||||||
|           { |  | ||||||
| 			"name": "from", |  | ||||||
|             "type": "Person" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
| 			"name": "to", |  | ||||||
|             "type": "Person[]" |  | ||||||
|           }, |  | ||||||
|           { |  | ||||||
| 			"name": "contents", |  | ||||||
|             "type": "string" |  | ||||||
|           } |  | ||||||
|         ] |  | ||||||
|       }, |  | ||||||
|       "primaryType": "Mail", |  | ||||||
|       "domain": { |  | ||||||
| 		"name": "Ether Mail", |  | ||||||
|         "version": "1", |  | ||||||
|         "chainId": 1, |  | ||||||
|         "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" |  | ||||||
|       }, |  | ||||||
|       "message": { |  | ||||||
|         "from": { |  | ||||||
| 			"name": "Cow", |  | ||||||
| 			"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" |  | ||||||
|         }, |  | ||||||
|         "to": {"baz": "foo"}, |  | ||||||
|         "contents": "Hello, Bob!" |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| ` |  | ||||||
| 	var malformedTypedData core.TypedData |  | ||||||
| 	err := json.Unmarshal([]byte(jsonTypedData), &malformedTypedData) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatalf("unmarshalling failed '%v'", err) |  | ||||||
| 	} |  | ||||||
| 	_, err = malformedTypedData.HashStruct("EIP712Domain", malformedTypedData.Domain.Map()) |  | ||||||
| 	if err != nil { |  | ||||||
| 		t.Errorf("Expected no error, got '%v'", err) |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func TestFormatter(t *testing.T) { | func TestFormatter(t *testing.T) { | ||||||
| 	var d core.TypedData | 	var d core.TypedData | ||||||
| 	err := json.Unmarshal([]byte(jsonTypedData), &d) | 	err := json.Unmarshal([]byte(jsonTypedData), &d) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("unmarshalling failed '%v'", err) | 		t.Fatalf("unmarshalling failed '%v'", err) | ||||||
| 	} | 	} | ||||||
| 	formatted := d.Format() | 	formatted, _ := d.Format() | ||||||
| 	for _, item := range formatted { | 	for _, item := range formatted { | ||||||
| 		fmt.Printf("'%v'\n", item.Pprint(0)) | 		fmt.Printf("'%v'\n", item.Pprint(0)) | ||||||
| 	} | 	} | ||||||
| @@ -806,3 +327,82 @@ func TestFormatter(t *testing.T) { | |||||||
| 	j, _ := json.Marshal(formatted) | 	j, _ := json.Marshal(formatted) | ||||||
| 	fmt.Printf("'%v'\n", string(j)) | 	fmt.Printf("'%v'\n", string(j)) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func sign(typedData core.TypedData) ([]byte, []byte, error) { | ||||||
|  | 	domainSeparator, err := typedData.HashStruct("EIP712Domain", typedData.Domain.Map()) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	typedDataHash, err := typedData.HashStruct(typedData.PrimaryType, typedData.Message) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, nil, err | ||||||
|  | 	} | ||||||
|  | 	rawData := []byte(fmt.Sprintf("\x19\x01%s%s", string(domainSeparator), string(typedDataHash))) | ||||||
|  | 	sighash := crypto.Keccak256(rawData) | ||||||
|  | 	return typedDataHash, sighash, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func TestJsonFiles(t *testing.T) { | ||||||
|  | 	testfiles, err := ioutil.ReadDir("testdata/") | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("failed reading files: %v", err) | ||||||
|  | 	} | ||||||
|  | 	for i, fInfo := range testfiles { | ||||||
|  | 		if !strings.HasSuffix(fInfo.Name(), "json") { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		expectedFailure := strings.HasPrefix(fInfo.Name(), "expfail") | ||||||
|  | 		data, err := ioutil.ReadFile(path.Join("testdata", fInfo.Name())) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Errorf("Failed to read file %v: %v", fInfo.Name(), err) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		var typedData core.TypedData | ||||||
|  | 		err = json.Unmarshal([]byte(data), &typedData) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Errorf("Test %d, file %v, json unmarshalling failed: %v", i, fInfo.Name(), err) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		_, _, err = sign(typedData) | ||||||
|  | 		fmt.Printf("Error %v\n", err) | ||||||
|  | 		if err != nil && !expectedFailure { | ||||||
|  | 			t.Errorf("Test %d failed, file %v: %v", i, fInfo.Name(), err) | ||||||
|  | 		} | ||||||
|  | 		if expectedFailure && err == nil { | ||||||
|  | 			t.Errorf("Test %d succeeded (expected failure), file %v: %v", i, fInfo.Name(), err) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TestFuzzerFiles tests some files that have been found by fuzzing to cause | ||||||
|  | // crashes or hangs. | ||||||
|  | func TestFuzzerFiles(t *testing.T) { | ||||||
|  | 	corpusdir := path.Join("testdata", "fuzzing") | ||||||
|  | 	testfiles, err := ioutil.ReadDir(corpusdir) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("failed reading files: %v", err) | ||||||
|  | 	} | ||||||
|  | 	verbose := false | ||||||
|  | 	for i, fInfo := range testfiles { | ||||||
|  | 		data, err := ioutil.ReadFile(path.Join(corpusdir, fInfo.Name())) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Errorf("Failed to read file %v: %v", fInfo.Name(), err) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		var typedData core.TypedData | ||||||
|  | 		err = json.Unmarshal([]byte(data), &typedData) | ||||||
|  | 		if err != nil { | ||||||
|  | 			t.Errorf("Test %d, file %v, json unmarshalling failed: %v", i, fInfo.Name(), err) | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
|  | 		_, err = typedData.EncodeData("EIP712Domain", typedData.Domain.Map(), 1) | ||||||
|  | 		if verbose && err != nil { | ||||||
|  | 			fmt.Printf("%d, EncodeData[1] err: %v\n", i, err) | ||||||
|  | 		} | ||||||
|  | 		_, err = typedData.EncodeData(typedData.PrimaryType, typedData.Message, 1) | ||||||
|  | 		if verbose && err != nil { | ||||||
|  | 			fmt.Printf("%d, EncodeData[2] err: %v\n", i, err) | ||||||
|  | 		} | ||||||
|  | 		typedData.Format() | ||||||
|  | 	} | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								signer/core/testdata/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								signer/core/testdata/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | ### EIP 712 tests | ||||||
|  |  | ||||||
|  | These tests are json files which are converted into eip-712 typed data.  | ||||||
|  | All files are expected to be proper json, and tests will fail if they are not.  | ||||||
|  | Files that begin with `expfail' are expected to not pass the hashstruct construction.  | ||||||
							
								
								
									
										60
									
								
								signer/core/testdata/arrays-1.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								signer/core/testdata/arrays-1.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Foo": [ | ||||||
|  |       { | ||||||
|  |         "name": "addys", | ||||||
|  |         "type": "address[]" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "stringies", | ||||||
|  |         "type": "string[]" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "inties", | ||||||
|  |         "type": "uint[]" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Foo", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Lorem", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "addys": [ | ||||||
|  |       "0x0000000000000000000000000000000000000001", | ||||||
|  |       "0x0000000000000000000000000000000000000002", | ||||||
|  |       "0x0000000000000000000000000000000000000003" | ||||||
|  |     ], | ||||||
|  |     "stringies": [ | ||||||
|  |       "lorem", | ||||||
|  |       "ipsum", | ||||||
|  |       "dolores" | ||||||
|  |     ], | ||||||
|  |     "inties": [ | ||||||
|  |       "0x0000000000000000000000000000000000000001", | ||||||
|  |       "3", | ||||||
|  |       4.0 | ||||||
|  |     ] | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										54
									
								
								signer/core/testdata/custom_arraytype.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								signer/core/testdata/custom_arraytype.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Person[]" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "contents", | ||||||
|  |         "type": "string" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "from": { "name": "Cow"}, | ||||||
|  |     "to": [{ "name": "Moose"},{ "name": "Goose"}], | ||||||
|  |     "contents": "Hello, Bob!" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										76
									
								
								signer/core/testdata/eip712.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								signer/core/testdata/eip712.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "test2", | ||||||
|  |         "type": "uint8" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "wallet", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "contents", | ||||||
|  |         "type": "string" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "from": { | ||||||
|  |       "name": "Cow", | ||||||
|  |       "test": "3", | ||||||
|  |       "test2": 5.0, | ||||||
|  |       "wallet": "0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" | ||||||
|  |     }, | ||||||
|  |     "to": { | ||||||
|  |       "name": "Bob", | ||||||
|  |       "test": "0", | ||||||
|  |       "test2": 5, | ||||||
|  |       "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" | ||||||
|  |     }, | ||||||
|  |     "contents": "Hello, Bob!" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								signer/core/testdata/expfail_arraytype_overload.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								signer/core/testdata/expfail_arraytype_overload.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "wallet", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person[]": [ | ||||||
|  |       { | ||||||
|  |         "name": "baz", | ||||||
|  |         "type": "string" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Person[]" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "contents", | ||||||
|  |         "type": "string" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "from": { | ||||||
|  |       "name": "Cow", | ||||||
|  |       "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" | ||||||
|  |     }, | ||||||
|  |     "to": {"baz": "foo"}, | ||||||
|  |     "contents": "Hello, Bob!" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								signer/core/testdata/expfail_datamismatch_1.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								signer/core/testdata/expfail_datamismatch_1.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "wallet", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "contents", | ||||||
|  |         "type": "Person" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "from": { | ||||||
|  |       "name": "Cow", | ||||||
|  |       "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" | ||||||
|  |     }, | ||||||
|  |     "to": { | ||||||
|  |       "name": "Bob", | ||||||
|  |       "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" | ||||||
|  |     }, | ||||||
|  |     "contents": "Hello, Bob!" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										76
									
								
								signer/core/testdata/expfail_extradata-1.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								signer/core/testdata/expfail_extradata-1.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256 ... and now for something completely different" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "test2", | ||||||
|  |         "type": "uint8" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "wallet", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "contents", | ||||||
|  |         "type": "string" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "from": { | ||||||
|  |       "name": "Cow", | ||||||
|  |       "test": "3", | ||||||
|  |       "test2": 5.0, | ||||||
|  |       "wallet": "0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" | ||||||
|  |     }, | ||||||
|  |     "to": { | ||||||
|  |       "name": "Bob", | ||||||
|  |       "test": "0", | ||||||
|  |       "test2": 5, | ||||||
|  |       "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" | ||||||
|  |     }, | ||||||
|  |     "contents": "Hello, Bob!" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								signer/core/testdata/expfail_extradata-2.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								signer/core/testdata/expfail_extradata-2.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "test2", | ||||||
|  |         "type": "uint8" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "wallet", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "contents", | ||||||
|  |         "type": "string" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "blahonga": "zonk bonk", | ||||||
|  |     "from": { | ||||||
|  |       "name": "Cow", | ||||||
|  |       "test": "3", | ||||||
|  |       "test2": 5.0, | ||||||
|  |       "wallet": "0xcD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" | ||||||
|  |     }, | ||||||
|  |     "to": { | ||||||
|  |       "name": "Bob", | ||||||
|  |       "test": "0", | ||||||
|  |       "test2": 5, | ||||||
|  |       "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" | ||||||
|  |     }, | ||||||
|  |     "contents": "Hello, Bob!" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								signer/core/testdata/expfail_malformeddomainkeys.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								signer/core/testdata/expfail_malformeddomainkeys.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "wallet", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "contents", | ||||||
|  |         "type": "string" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "vFAILFAILerifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "from": { | ||||||
|  |       "name": "Cow", | ||||||
|  |       "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" | ||||||
|  |     }, | ||||||
|  |     "to": { | ||||||
|  |       "name": "Bob", | ||||||
|  |       "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" | ||||||
|  |     }, | ||||||
|  |     "contents": "Hello, Bob!" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								signer/core/testdata/expfail_nonexistant_type.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								signer/core/testdata/expfail_nonexistant_type.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "wallet", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "contents", | ||||||
|  |         "type": "Blahonga" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "from": { | ||||||
|  |       "name": "Cow", | ||||||
|  |       "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" | ||||||
|  |     }, | ||||||
|  |     "to": { | ||||||
|  |       "name": "Bob", | ||||||
|  |       "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" | ||||||
|  |     }, | ||||||
|  |     "contents": "Hello, Bob!" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								signer/core/testdata/expfail_toolargeuint.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								signer/core/testdata/expfail_toolargeuint.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "test":"257" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								signer/core/testdata/expfail_toolargeuint2.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								signer/core/testdata/expfail_toolargeuint2.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "test":257 | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								signer/core/testdata/expfail_unconvertiblefloat.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								signer/core/testdata/expfail_unconvertiblefloat.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "test":"255.3" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								signer/core/testdata/expfail_unconvertiblefloat2.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								signer/core/testdata/expfail_unconvertiblefloat2.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "test": 255.3 | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								signer/core/testdata/fuzzing/2850f6ccf2d7f5f846dfb73119b60e09e712783f
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								signer/core/testdata/fuzzing/2850f6ccf2d7f5f846dfb73119b60e09e712783f
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "test":"255.3" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										60
									
								
								signer/core/testdata/fuzzing/36fb987a774011dc675e1b5246ac5c1d44d84d92
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								signer/core/testdata/fuzzing/36fb987a774011dc675e1b5246ac5c1d44d84d92
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Foo": [ | ||||||
|  |       { | ||||||
|  |         "name": "addys", | ||||||
|  |         "type": "address[]" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "stringies", | ||||||
|  |         "type": "string[]" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "inties", | ||||||
|  |         "type": "uint[]" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Foo", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Lorem", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "addys": [ | ||||||
|  |       "0x0000000000000000000000000000000000000001", | ||||||
|  |       "0x0000000000000000000000000000000000000002", | ||||||
|  |       "0x0000000000000000000000000000000000000003" | ||||||
|  |     ], | ||||||
|  |     "stringies": [ | ||||||
|  |       "lorem", | ||||||
|  |       "ipsum", | ||||||
|  |       "dolores" | ||||||
|  |     ], | ||||||
|  |     "inties": [ | ||||||
|  |       "0x0000000000000000000000000000000000000001", | ||||||
|  |       "3", | ||||||
|  |       4.0 | ||||||
|  |     ] | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										38
									
								
								signer/core/testdata/fuzzing/37ec7b55c7ba014cced204c5f9989d2d0eb9ff6d
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								signer/core/testdata/fuzzing/37ec7b55c7ba014cced204c5f9989d2d0eb9ff6d
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "uint256" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "test", | ||||||
|  |         "type": "uint8" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "Ether Mail", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingContract": "0xCCCcccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "test":257 | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								signer/core/testdata/fuzzing/582fa92154b784daa1faa293b695fa388fe34bf1
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								signer/core/testdata/fuzzing/582fa92154b784daa1faa293b695fa388fe34bf1
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | {"domain":{"version":"0","chainId":""}} | ||||||
							
								
								
									
										54
									
								
								signer/core/testdata/fuzzing/ab57cb2b2b5ce614efe13a47bc73814580f2cce8
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								signer/core/testdata/fuzzing/ab57cb2b2b5ce614efe13a47bc73814580f2cce8
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | |||||||
|  | {  "types": {  "":[   { | ||||||
|  |        "name": "name", | ||||||
|  |    "type":"string"    }, | ||||||
|  |    { | ||||||
|  |     "name":"version", | ||||||
|  |       "type": "string"    },     { | ||||||
|  |      "name": "chaiI", | ||||||
|  |     "type":"uint256 . ad nowretig omeedifere"     },     { | ||||||
|  |      "ae": "eifinC", | ||||||
|  |     "ty":"dess" | ||||||
|  |     } | ||||||
|  |  ], | ||||||
|  |   "Person":[ | ||||||
|  |      { | ||||||
|  |     "name":"name", | ||||||
|  |       "type": "string" | ||||||
|  |  },  { | ||||||
|  |      "name":"tes",    "type":"it8" | ||||||
|  |     }, | ||||||
|  |       {    "name":"t",      "tye":"uit8" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |        "a":"ale", | ||||||
|  |     "type": "ress" | ||||||
|  |      } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |    { | ||||||
|  |        "name":"from",    "type":"Person"     }, | ||||||
|  |    { | ||||||
|  |      "name": "to",        "type": "Person" | ||||||
|  |     }, | ||||||
|  |    { | ||||||
|  |      "name": "contents", | ||||||
|  |      "type": "string" | ||||||
|  |     } | ||||||
|  |    ] | ||||||
|  |  }, "primaryType": "Mail", | ||||||
|  |  "domain": { | ||||||
|  | "name":"theMail",    "version": "1", | ||||||
|  |     "chainId": "1", | ||||||
|  |     "verifyingntract": "0xCcccCCCcCCCCCCCcCCcCCCcCcccccC" | ||||||
|  |   }, | ||||||
|  |   "message": {   "from": { | ||||||
|  |     "name": "Cow", | ||||||
|  |      "test": "3", | ||||||
|  |       "est2":5.0, | ||||||
|  |       "llt": "0xcD2a3938E13D947E0bE734DfDD86"   },   "to": {     "name": "Bob", | ||||||
|  |     "ts":"", | ||||||
|  |      "tet2": 5, | ||||||
|  |      "allet": "0bBBBBbbBBbbbbBbbBbbbbBBBbB" | ||||||
|  |   }, | ||||||
|  |     "contents": "Hello, Bob!"  } | ||||||
|  | } | ||||||
							
								
								
									
										64
									
								
								signer/core/testdata/fuzzing/e4303e23ca34fbbc43164a232b2caa7a3af2bf8d
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								signer/core/testdata/fuzzing/e4303e23ca34fbbc43164a232b2caa7a3af2bf8d
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | { | ||||||
|  |   "types": { | ||||||
|  |     "EIP712Domain": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "version", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "chainId", | ||||||
|  |         "type": "int" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "verifyingContract", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Person": [ | ||||||
|  |       { | ||||||
|  |         "name": "name", | ||||||
|  |         "type": "string" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "wallet", | ||||||
|  |         "type": "address" | ||||||
|  |       } | ||||||
|  |     ], | ||||||
|  |     "Mail": [ | ||||||
|  |       { | ||||||
|  |         "name": "from", | ||||||
|  |         "type": "Person" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "to", | ||||||
|  |         "type": "Mail" | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         "name": "s", | ||||||
|  |         "type": "Person" | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }, | ||||||
|  |   "primaryType": "Mail", | ||||||
|  |   "domain": { | ||||||
|  |     "name": "l", | ||||||
|  |     "version": "1", | ||||||
|  |     "chainId": "", | ||||||
|  |     "verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" | ||||||
|  |   }, | ||||||
|  |   "message": { | ||||||
|  |     "from": { | ||||||
|  |       "name": "", | ||||||
|  |       "wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826" | ||||||
|  |     }, | ||||||
|  |     "to": { | ||||||
|  |       "name": "", | ||||||
|  |       "wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB" | ||||||
|  |     }, | ||||||
|  |     "": "" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								signer/core/testdata/fuzzing/f658340af009dd4a35abe645a00a7b732bc30921
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								signer/core/testdata/fuzzing/f658340af009dd4a35abe645a00a7b732bc30921
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | {"types":{"0":[{}]}} | ||||||
		Reference in New Issue
	
	Block a user