Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: signer: support encoding fixed and dynamic arrays to fully comply with EIP 712 spec #30620

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 37 additions & 34 deletions signer/core/apitypes/signed_data_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@ package apitypes

import (
"bytes"
"encoding/json"
"fmt"
"math/big"
"os"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestBytesPadding(t *testing.T) {
Expand Down Expand Up @@ -244,45 +250,42 @@ func TestConvertAddressDataToSlice(t *testing.T) {
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{},
type testDataInput struct {
Name string `json:"name"`
Domain TypedDataDomain `json:"domain"`
PrimaryType string `json:"primaryType"`
Types Types `json:"types"`
Message TypedDataMessage `json:"data"`
Digest string `json:"digest"`
}
fc, err := os.ReadFile("./testdata/typed-data.json")
require.NoError(t, err, "error reading test data file")

if err := typedData.validate(); err != nil {
t.Errorf("expected typed data to pass validation, got: %v", err)
}
var tests []testDataInput
err = json.Unmarshal(fc, &tests)
require.NoError(t, err, "error unmarshalling test data file contents")

// Should be able to accept dynamic arrays
typedData.Types["BulkOrder"][0].Type = "OrderComponents[]"
for _, tc := range tests {
t.Run(tc.Name, func(t *testing.T) {
t.Parallel()

if err := typedData.validate(); err != nil {
t.Errorf("expected typed data to pass validation, got: %v", err)
}
td := TypedData{
Types: tc.Types,
PrimaryType: tc.PrimaryType,
Domain: tc.Domain,
Message: tc.Message,
}

domainSeparator, tErr := td.HashStruct("EIP712Domain", td.Domain.Map())
assert.NoError(t, tErr, "failed to hash domain separator: %v", tErr)

messageHash, tErr := td.HashStruct(td.PrimaryType, td.Message)
assert.NoError(t, tErr, "failed to hash message: %v", tErr)

// Should be able to accept standard types
typedData.Types["BulkOrder"][0].Type = "OrderComponents"
digest := crypto.Keccak256Hash([]byte(fmt.Sprintf("%s%s%s", "\x19\x01", string(domainSeparator), string(messageHash))))
assert.Equal(t, tc.Digest, digest.String(), "digest doesn't not match")

if err := typedData.validate(); err != nil {
t.Errorf("expected typed data to pass validation, got: %v", err)
assert.NoError(t, td.validate(), "validation failed", tErr)
})
}
}
Loading