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

ERC-7730 to EIP-712 conversion allows invalid paths #27 #31

Merged
merged 5 commits into from
Sep 26, 2024
Merged
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
4 changes: 2 additions & 2 deletions src/erc7730/model/display.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from erc7730.model.base import BaseLibraryModel
from erc7730.model.types import Id
from erc7730.model.types import Id, Path
from typing import Annotated, Any, Dict, ForwardRef, Optional, Union
from enum import Enum
from pydantic import Discriminator, RootModel, Field as PydanticField, Tag
Expand Down Expand Up @@ -123,7 +123,7 @@ def get_param_discriminator(v: Any) -> str | None:


class FieldDescription(BaseLibraryModel):
path: Optional[str] = None
path: Optional[Path] = None
field_id: Optional[Id] = PydanticField(None, alias="$id")
label: str
format: FieldFormat
Expand Down
1 change: 1 addition & 0 deletions src/erc7730/model/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@

Id = Ann[str, Field(min_length=1)]
ContractAddress = Ann[str, Field(min_length=0, max_length=64, pattern=r"^[a-zA-Z0-9_\-]+$")]
Path = Ann[str, Field(pattern=r"^[a-zA-Z0-9.\[\]_]+")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

206 changes: 206 additions & 0 deletions tests/resources/eip712_wrong_path.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
{
"$schema": "../../clear-signing-erc7730-registry/specs/erc7730-v1.schema.json",

"metadata": {
"owner": "Uniswap",
"info": {
"legalName": "Uniswap Labs",
"lastUpdate": "2021-12-14T00:00:00Z",
"url": "https://uniswap.org/"
}
},

"context": {
"eip712": {
"domain": {
"name": "Permit2"
},
"deployments": [
{
"chainId": 1,
"address": "0x000000000022D473030F116dDEE9F6B43aC78BA3"
}
],
"schemas": [
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"PermitDetails": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint160"
},
{
"name": "expiration",
"type": "uint48"
},
{
"name": "nonce",
"type": "uint48"
}
],
"PermitBatch": [
{
"name": "details",
"type": "PermitDetails[]"
},
{
"name": "spender",
"type": "address"
},
{
"name": "sigDeadline",
"type": "uint256"
}
]
},
"primaryType": "PermitBatch"
},
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"PermitDetails": [
{
"name": "token",
"type": "address"
},
{
"name": "amount",
"type": "uint160"
},
{
"name": "expiration",
"type": "uint48"
},
{
"name": "nonce",
"type": "uint48"
}
],
"PermitSingle": [
{
"name": "details",
"type": "PermitDetails"
},
{
"name": "spender",
"type": "address"
},
{
"name": "sigDeadline",
"type": "uint256"
}
]
},
"primaryType": "PermitSingle"
}
]
}
},

"display": {
"formats": {

"PermitSingle": {
"$id": "Permit2 Permit Single",
"intent": "Authorize spending of token",
"fields": [
{
"path": "@spender",
"label": "Spender",
"format": "addressName"
},
{
"path": "details.amount[]",
"label": "Amount allowance",
"format": "tokenAmount",
"params": {
"tokenPath": "details.token"
}
},
{
"path": "details$.expiration",
"label": "Approval expires",
"format": "date",
"params": {
"encoding": "timestamp"
}
}
],
"required": [
"spender",
"details.amount"
],
"screens": {}
},

"PermitBatch": {
"$id": "Permit2 Permit Batch",
"intent": "Authorize spending of tokens",
"fields": [
{
"path": ";spender",
"label": "Spender",
"format": "addressName"
},
{
"path": "|details.[]",
"fields": [
{
"path": "#amount",
"label": "Amount allowance",
"format": "tokenAmount",
"params": {
"tokenPath": "token"
}
},
{
"path": "%expiration",
"label": "Approval expires",
"format": "date",
"params": {
"encoding": "timestamp"
}
}
]
}
],
"required": [
"spender",
"details"
],
"screens": {}
}
}
}
}
19 changes: 14 additions & 5 deletions tests/src/erc7730/common/test_datamodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import json
from jsonschema import validate, exceptions
from prettydiff import print_diff
from pydantic_core import ValidationError

files = glob.glob("clear-signing-erc7730-registry/registry/*/*[!stETH].json")

files = glob.glob("clear-signing-erc7730-registry/registry/*/*.json")
with open("clear-signing-erc7730-registry/specs/erc7730-v1.schema.json", "r") as file:
schema = json.load(file)

Expand All @@ -30,21 +32,28 @@ def test_from_erc7730(file: str) -> None:
assert json_from_model == original_dict_with_includes


abi_item_json_str = '{"name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"type":"function"}'


def test_23_unset_attributes_must_not_be_serialized_as_set() -> None:
abi_item_json_str = '{"name":"approve","inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"outputs":[{"name":"","type":"bool"}],"type":"function"}'
abi_item_json = json.loads(abi_item_json_str)
abi_item = AbiJsonSchemaItem.model_validate(abi_item_json, strict=False)
abi_item_json_str_deserialized = json_file_from_model(AbiJsonSchemaItem, abi_item)
print_diff(abi_item_json_str, abi_item_json_str_deserialized)
assert abi_item_json_str == abi_item_json_str_deserialized


display_json_str = '{"formats":{"Permit":{"screens":{"stax":[{"type":"propertyPage","label":"DAI Permit","content":["spender","value","deadline"]}]}}}}'
def test_27_erc7730_allows_invalid_paths() -> None:
errors = None
try:
ERC7730Descriptor.load_or_none(Path("tests/resources/eip712_wrong_path.json"))
except ValidationError as ex:
assert ex.error_count() == 4
errors = ex.errors
finally:
assert errors is not None


def test_22_screens_serialization_not_symmetric() -> None:
display_json_str = '{"formats":{"Permit":{"screens":{"stax":[{"type":"propertyPage","label":"DAI Permit","content":["spender","value","deadline"]}]}}}}'
display_json = json.loads(display_json_str)
display = Display.model_validate(display_json, strict=True)
display_json_deserialized = json_file_from_model(Display, display)
Expand Down
2 changes: 2 additions & 0 deletions tests/src/erc7730/mapper/test_mapper.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import json
from jsonschema import validate, exceptions
from pathlib import Path

from erc7730.common.pydantic import json_file_from_model
from erc7730.model.erc7730_descriptor import ERC7730Descriptor
from erc7730.mapper.mapper import to_eip712_mapper, to_erc7730_mapper
from eip712 import EIP712DAppDescriptor
import pytest
import glob


inputs = glob.glob("clear-signing-erc7730-registry/registry/*/eip712*.json")

with open("tests/resources/eip712.schema.json", "r") as file:
Expand Down
Loading