Skip to content

Commit

Permalink
signer/core: don't require capital lettered reference types (ethereum…
Browse files Browse the repository at this point in the history
  • Loading branch information
holiman authored Jan 20, 2023
1 parent 50e6539 commit 4f4a25d
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 21 deletions.
31 changes: 10 additions & 21 deletions signer/core/apitypes/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ import (
"sort"
"strconv"
"strings"
"unicode"
"unicode/utf8"

"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common"
Expand All @@ -38,7 +36,7 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)

var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Z](\w*)(\[\])?$`)
var typedDataReferenceTypeRegexp = regexp.MustCompile(`^[A-Za-z](\w*)(\[\])?$`)

type ValidationInfo struct {
Typ string `json:"type"`
Expand Down Expand Up @@ -224,15 +222,6 @@ func (t *Type) typeName() string {
return t.Type
}

func (t *Type) isReferenceType() bool {
if len(t.Type) == 0 {
return false
}
// Reference types must have a leading uppercase character
r, _ := utf8.DecodeRuneInString(t.Type)
return unicode.IsUpper(r)
}

type Types map[string][]Type

type TypePriority struct {
Expand Down Expand Up @@ -731,15 +720,15 @@ func (t Types) validate() error {
if typeKey == typeObj.Type {
return fmt.Errorf("type %q cannot reference itself", typeObj.Type)
}
if typeObj.isReferenceType() {
if _, exist := t[typeObj.typeName()]; !exist {
return fmt.Errorf("reference type %q is undefined", typeObj.Type)
}
if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) {
return fmt.Errorf("unknown reference type %q", typeObj.Type)
}
} else if !isPrimitiveTypeValid(typeObj.Type) {
return fmt.Errorf("unknown type %q", typeObj.Type)
if isPrimitiveTypeValid(typeObj.Type) {
continue
}
// Must be reference type
if _, exist := t[typeObj.typeName()]; !exist {
return fmt.Errorf("reference type %q is undefined", typeObj.Type)
}
if !typedDataReferenceTypeRegexp.MatchString(typeObj.Type) {
return fmt.Errorf("unknown reference type %q", typeObj.Type)
}
}
}
Expand Down
150 changes: 150 additions & 0 deletions signer/core/signed_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -848,3 +848,153 @@ func TestGnosisSafe(t *testing.T) {
t.Fatal("expected equality")
}
}

var complexTypedDataLCRefType = `
{
"types": {
"EIP712Domain": [
{
"name": "chainId",
"type": "uint256"
},
{
"name": "name",
"type": "string"
},
{
"name": "verifyingContract",
"type": "address"
},
{
"name": "version",
"type": "string"
}
],
"Action": [
{
"name": "action",
"type": "string"
},
{
"name": "params",
"type": "string"
}
],
"cCell": [
{
"name": "capacity",
"type": "string"
},
{
"name": "lock",
"type": "string"
},
{
"name": "type",
"type": "string"
},
{
"name": "data",
"type": "string"
},
{
"name": "extraData",
"type": "string"
}
],
"Transaction": [
{
"name": "DAS_MESSAGE",
"type": "string"
},
{
"name": "inputsCapacity",
"type": "string"
},
{
"name": "outputsCapacity",
"type": "string"
},
{
"name": "fee",
"type": "string"
},
{
"name": "action",
"type": "Action"
},
{
"name": "inputs",
"type": "cCell[]"
},
{
"name": "outputs",
"type": "cCell[]"
},
{
"name": "digest",
"type": "bytes32"
}
]
},
"primaryType": "Transaction",
"domain": {
"chainId": "56",
"name": "da.systems",
"verifyingContract": "0x0000000000000000000000000000000020210722",
"version": "1"
},
"message": {
"DAS_MESSAGE": "SELL mobcion.bit FOR 100000 CKB",
"inputsCapacity": "1216.9999 CKB",
"outputsCapacity": "1216.9998 CKB",
"fee": "0.0001 CKB",
"digest": "0x53a6c0f19ec281604607f5d6817e442082ad1882bef0df64d84d3810dae561eb",
"action": {
"action": "start_account_sale",
"params": "0x00"
},
"inputs": [
{
"capacity": "218 CKB",
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
"type": "account-cell-type,0x01,0x",
"data": "{ account: mobcion.bit, expired_at: 1670913958 }",
"extraData": "{ status: 0, records_hash: 0x55478d76900611eb079b22088081124ed6c8bae21a05dd1a0d197efcc7c114ce }"
}
],
"outputs": [
{
"capacity": "218 CKB",
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
"type": "account-cell-type,0x01,0x",
"data": "{ account: mobcion.bit, expired_at: 1670913958 }",
"extraData": "{ status: 1, records_hash: 0x55478d76900611eb079b22088081124ed6c8bae21a05dd1a0d197efcc7c114ce }"
},
{
"capacity": "201 CKB",
"lock": "das-lock,0x01,0x051c152f77f8efa9c7c6d181cc97ee67c165c506...",
"type": "account-sale-cell-type,0x01,0x",
"data": "0x1209460ef3cb5f1c68ed2c43a3e020eec2d9de6e...",
"extraData": ""
}
]
}
}
`

func TestComplexTypedDataWithLowercaseReftype(t *testing.T) {
var td apitypes.TypedData
err := json.Unmarshal([]byte(complexTypedDataLCRefType), &td)
if err != nil {
t.Fatalf("unmarshalling failed '%v'", err)
}
_, sighash, err := sign(td)
if err != nil {
t.Fatal(err)
}
expSigHash := common.FromHex("0x49191f910874f0148597204d9076af128d4694a7c4b714f1ccff330b87207bff")
if !bytes.Equal(expSigHash, sighash) {
t.Fatalf("Error, got %x, wanted %x", sighash, expSigHash)
}
}

0 comments on commit 4f4a25d

Please sign in to comment.