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

Exception is thrown when parsing typedData (bad encoding) #12

Open
Toporin opened this issue Sep 13, 2022 · 0 comments
Open

Exception is thrown when parsing typedData (bad encoding) #12

Toporin opened this issue Sep 13, 2022 · 0 comments

Comments

@Toporin
Copy link

Toporin commented Sep 13, 2022

When I try to encode typedData from various dapps, an exception is sometimes thrown with the following error:

exception while parsing typedData: Value '2' of type <class 'str'> cannot be encoded by UnsignedIntegerEncoder

For example:

`

typed_data= {"types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"},{"name":"verifyingContract","type":"address"}],"OrderComponents":[{"name":"offerer","type":"address"},{"name":"zone","type":"address"},{"name":"offer","type":"OfferItem[]"},{"name":"consideration","type":"ConsiderationItem[]"},{"name":"orderType","type":"uint8"},{"name":"startTime","type":"uint256"},{"name":"endTime","type":"uint256"},{"name":"zoneHash","type":"bytes32"},{"name":"salt","type":"uint256"},{"name":"conduitKey","type":"bytes32"},{"name":"counter","type":"uint256"}],"OfferItem":[{"name":"itemType","type":"uint8"},{"name":"token","type":"address"},{"name":"identifierOrCriteria","type":"uint256"},{"name":"startAmount","type":"uint256"},{"name":"endAmount","type":"uint256"}],"ConsiderationItem":[{"name":"itemType","type":"uint8"},{"name":"token","type":"address"},{"name":"identifierOrCriteria","type":"uint256"},{"name":"startAmount","type":"uint256"},{"name":"endAmount","type":"uint256"},{"name":"recipient","type":"address"}]},"primaryType":"OrderComponents","domain":{"name":"Seaport","version":"1.1","chainId":"1","verifyingContract":"0x00000000006c3852cbEf3e08E8dF289169EdE581"},"message":{"offerer":"0xF23aDCE99089BD884Dfc860a4178046E26Efc79F","offer":[{"itemType":"2","token":"0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85","identifierOrCriteria":"79283735726345475554244090083354043673577121378327128667043370997501889156666","startAmount":"1","endAmount":"1"}],"consideration":[{"itemType":"1","token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","identifierOrCriteria":"0","startAmount":"309075000000000000","endAmount":"309075000000000000","recipient":"0xF23aDCE99089BD884Dfc860a4178046E26Efc79F"},{"itemType":"1","token":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2","identifierOrCriteria":"0","startAmount":"7925000000000000","endAmount":"7925000000000000","recipient":"0x0000a26b00c1F0DF003000390027140000fAa719"}],"startTime":"1662714094","endTime":"1662973294","orderType":"2","zone":"0x004C00500000aD104D7DBd00e3ae0A5C00560C00","zoneHash":"0x0000000000000000000000000000000000000000000000000000000000000000","salt":"11315322929827309","conduitKey":"0x0000007b02230091a7ed01230072f7006a004d60a8d4e71d599b8104250f0000","totalOriginalConsiderationItems":"2","counter":"0"}}
from py_eth_sig_utils import eip712
msg_hash= eip712.encoding.encode_typed_data(typed_data)
`

This returns the following error:

Value '2' of type <class 'str'> cannot be encoded by UnsignedIntegerEncoder

As far as I can tell, this is due to wrong encoding of the typedData, e.g. "orderType":"2" (a string) despite the fact that "orderType" is defined as a uint8 and py-eth-sig-utils expects an int, not a string. A similar issue arises with "bytes32" types.

Since it appears a significant number of dapps mismatch encoding for "int", "uint" and "bytes*" as string, is it possible to sanitize format before encoding and correct any wrong encoding instead of throwing exception?**

Here is a quick and dirty patch that seems to do the trick (in encoding.py):

def encode_value(dataType, value, types):
    print(f"DEBUG py_eth_sig_utils: in encode_value: data_type:{dataType}, value:{value}")
    if (dataType == 'string'):
        return encode_single('bytes32', utils.sha3(value))
    elif (dataType == 'bytes'):
        return encode_single('bytes32', utils.sha3(utils.scan_bin(value)))
    elif (types.get(dataType)):
        return encode_single('bytes32', utils.sha3(encode_data(dataType, value, types)))
    elif (dataType.endswith("]")):
        arrayType = dataType[:dataType.index("[")]
        return encode_single('bytes32', utils.sha3(b"".join([ encode_data(arrayType, arrayValue, types) for arrayValue in value ])))
    else:
        #print(f"DEBUG py_eth_sig_utils: in encode_value: data_type:{dataType}, value:{value}")
        if (dataType.startswith("uint") or dataType.startswith("int")) and isinstance(value, str):
            print(f"DEBUG py_eth_sig_utils: in encode_value: convert string to int!")
            value= int(value)
        if (dataType.startswith("bytes")) and isinstance(value, str):
            print(f"DEBUG py_eth_sig_utils: in encode_value: convert string to bytes!")
            if value.startswith("0x"):
                value= value[2:]
            value= bytes.fromhex(value)
        return encode_single(dataType, value)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant