signer/core/apitypes: support fixed size arrays for EIP-712 typed data (#30175)

When attempting to hash a typed data struct that includes a type
reference with a fixed-size array, the validation process fails.
According to EIP-712, arrays can be either fixed-size or dynamic,
denoted by `Type[n]` or `Type[]` respectively, although it appears this
currently isn't supported.

This change modifies  the validation logic to accommodate types
containing fixed-size arrays.
pull/30364/head
markus 3 months ago committed by GitHub
parent 0e5546f032
commit ea3b5095f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 46
      signer/core/apitypes/signed_data_internal_test.go
  2. 7
      signer/core/apitypes/types.go

@ -240,3 +240,49 @@ func TestConvertAddressDataToSlice(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
} }
func TestTypedDataArrayValidate(t *testing.T) {
t.Parallel()
typedData := TypedData{
Types: Types{
"BulkOrder": []Type{
// Should be able to accept fixed size arrays
{Name: "tree", Type: "OrderComponents[2][2]"},
},
"OrderComponents": []Type{
{Name: "offerer", Type: "address"},
{Name: "amount", Type: "uint8"},
},
"EIP712Domain": []Type{
{Name: "name", Type: "string"},
{Name: "version", Type: "string"},
{Name: "chainId", Type: "uint8"},
{Name: "verifyingContract", Type: "address"},
},
},
PrimaryType: "BulkOrder",
Domain: TypedDataDomain{
VerifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC",
},
Message: TypedDataMessage{},
}
if err := typedData.validate(); err != nil {
t.Errorf("expected typed data to pass validation, got: %v", err)
}
// Should be able to accept dynamic arrays
typedData.Types["BulkOrder"][0].Type = "OrderComponents[]"
if err := typedData.validate(); err != nil {
t.Errorf("expected typed data to pass validation, got: %v", err)
}
// Should be able to accept standard types
typedData.Types["BulkOrder"][0].Type = "OrderComponents"
if err := typedData.validate(); err != nil {
t.Errorf("expected typed data to pass validation, got: %v", err)
}
}

@ -40,7 +40,7 @@ import (
"github.com/holiman/uint256" "github.com/holiman/uint256"
) )
var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Za-z](\w*)(\[\])?$`) var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Za-z](\w*)(\[\d*\])*$`)
type ValidationInfo struct { type ValidationInfo struct {
Typ string `json:"type"` Typ string `json:"type"`
@ -332,8 +332,9 @@ func (t *Type) isArray() bool {
// typeName returns the canonical name of the type. If the type is 'Person[]', then // typeName returns the canonical name of the type. If the type is 'Person[]', then
// this method returns 'Person' // this method returns 'Person'
func (t *Type) typeName() string { func (t *Type) typeName() string {
if strings.HasSuffix(t.Type, "[]") { if strings.Contains(t.Type, "[") {
return strings.TrimSuffix(t.Type, "[]") re := regexp.MustCompile(`\[\d*\]`)
return re.ReplaceAllString(t.Type, "")
} }
return t.Type return t.Type
} }

Loading…
Cancel
Save