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.
This commit is contained in:
parent
0e5546f032
commit
ea3b5095f4
@ -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…
Reference in New Issue
Block a user