From 0c7e97c748c2bdd8af00aff451ee1263dbeeeb88 Mon Sep 17 00:00:00 2001 From: Mikko Ohtamaa Date: Fri, 2 Feb 2024 11:26:51 +0100 Subject: [PATCH] Fixed terms_of_service dependency issues. Black formatting. --- eth_defi/deploy.py | 2 - eth_defi/enzyme/generic_adapter_vault.py | 3 +- eth_defi/etherscan/__init__.py | 2 +- eth_defi/etherscan/verify.py | 2 +- eth_defi/foundry/__init__.py | 2 +- eth_defi/foundry/forge.py | 36 +++++------ eth_defi/terms_of_service/__init__.py | 1 + .../terms_of_service/acceptance_message.py | 63 +++++++++++++++++++ pyproject.toml | 8 ++- tests/enzyme/test_guard_enzyme_uniswap_v2.py | 3 +- tests/enzyme/test_guard_enzyme_uniswap_v3.py | 2 +- tests/rpc/test_forge_deploy.py | 3 +- tests/test_reorganisation_monitor_polygon.py | 1 + 13 files changed, 95 insertions(+), 33 deletions(-) create mode 100644 eth_defi/terms_of_service/__init__.py create mode 100644 eth_defi/terms_of_service/acceptance_message.py diff --git a/eth_defi/deploy.py b/eth_defi/deploy.py index ce5cb02f..c1238658 100644 --- a/eth_defi/deploy.py +++ b/eth_defi/deploy.py @@ -95,8 +95,6 @@ def deploy_contract( return instance - - def get_or_create_contract_registry(web3: Web3) -> ContractRegistry: """Get a contract registry associated with a Web3 connection. diff --git a/eth_defi/enzyme/generic_adapter_vault.py b/eth_defi/enzyme/generic_adapter_vault.py index 3b569413..378f0b3c 100644 --- a/eth_defi/enzyme/generic_adapter_vault.py +++ b/eth_defi/enzyme/generic_adapter_vault.py @@ -235,7 +235,6 @@ def deploy_vault_with_generic_adapter( logger.info("VaultUSDCPaymentForwarder is %s deployed at %s", payment_forwarder.address, tx_hash.hex()) if not mock_guard: - # When swap is performed, the tokens will land on the integration contract # and this contract must be listed as the receiver. # Enzyme will then internally move tokens to its vault from here. @@ -297,7 +296,7 @@ def deploy_vault_with_generic_adapter( match web3.eth.chain_id: case 137: uniswap_v3_router = UNISWAP_V3_DEPLOYMENTS["polygon"]["router"] - uniswap_v2_router= None + uniswap_v2_router = None case 1: uniswap_v2_router = UNISWAP_V2_DEPLOYMENTS["ethereum"]["router"] uniswap_v3_router = UNISWAP_V3_DEPLOYMENTS["ethereum"]["router"] diff --git a/eth_defi/etherscan/__init__.py b/eth_defi/etherscan/__init__.py index 720c3b52..a52f5aab 100644 --- a/eth_defi/etherscan/__init__.py +++ b/eth_defi/etherscan/__init__.py @@ -1,4 +1,4 @@ """Etherscan integration. Verify smart contracts on Etherscan, Polygonscan, BSCScan and other Etherscan software-as-a-service offerings. -""" \ No newline at end of file +""" diff --git a/eth_defi/etherscan/verify.py b/eth_defi/etherscan/verify.py index 408c5dc6..4c97e526 100644 --- a/eth_defi/etherscan/verify.py +++ b/eth_defi/etherscan/verify.py @@ -6,4 +6,4 @@ Currently no Web3.py direct integration available. Use :py:func:`eth_defi.foundry.forge.deploy_contract_with_forge` to deploy contracts that are verified on Etherscan. -""" \ No newline at end of file +""" diff --git a/eth_defi/foundry/__init__.py b/eth_defi/foundry/__init__.py index 2a1c69e9..3a90a16c 100644 --- a/eth_defi/foundry/__init__.py +++ b/eth_defi/foundry/__init__.py @@ -1,4 +1,4 @@ """Forge smart contract development toolchain integration. - Compile and deploy verified smart contracts -""" \ No newline at end of file +""" diff --git a/eth_defi/foundry/forge.py b/eth_defi/foundry/forge.py index 0c342273..47d685c5 100644 --- a/eth_defi/foundry/forge.py +++ b/eth_defi/foundry/forge.py @@ -32,7 +32,7 @@ #: Crash unless forge completes in 3 minutes #: -DEFAULT_TIMEOUT = 3*60 +DEFAULT_TIMEOUT = 3 * 60 class ForgeFailed(Exception): @@ -208,28 +208,29 @@ def deploy_contract_with_forge( cmd_line = [ forge, "create", - "--rpc-url", json_rpc_url, - "--nonce", str(deployer.allocate_nonce()), + "--rpc-url", + json_rpc_url, + "--nonce", + str(deployer.allocate_nonce()), ] if etherscan_api_key: # Tuned retry parameters # https://github.com/foundry-rs/foundry/issues/6953 cmd_line += [ - "--etherscan-api-key", etherscan_api_key, + "--etherscan-api-key", + etherscan_api_key, "--verify", - "--retries", "10", - "--delay", "30", + "--retries", + "10", + "--delay", + "30", ] - cmd_line += [ - f"{src_contract_file}:{contract_name}" - ] + cmd_line += [f"{src_contract_file}:{contract_name}"] if constructor_args: - cmd_line += [ - "--constructor-args" - ] + cmd_line += ["--constructor-args"] for arg in constructor_args: cmd_line.append(arg) @@ -245,7 +246,8 @@ def deploy_contract_with_forge( cmd_line = [ forge, "create", - "--private-key", deployer.private_key.hex(), + "--private-key", + deployer.private_key.hex(), ] + cmd_line[2:] # Py 3.11 only @@ -270,11 +272,7 @@ def deploy_contract_with_forge( # Mad Web3.py API contract_address = ChecksumAddress(HexAddress(HexStr(contract_address))) - instance = get_deployed_contract( - web3, - contract_abi, - contract_address - ) + instance = get_deployed_contract(web3, contract_abi, contract_address) if register_for_tracing: instance.name = contract_name @@ -287,4 +285,4 @@ def deploy_contract_with_forge( RaisedException=ForgeFailed, ) - return instance, tx_hash \ No newline at end of file + return instance, tx_hash diff --git a/eth_defi/terms_of_service/__init__.py b/eth_defi/terms_of_service/__init__.py new file mode 100644 index 00000000..1cf30209 --- /dev/null +++ b/eth_defi/terms_of_service/__init__.py @@ -0,0 +1 @@ +"""Copied around due to Python packaging issues""" diff --git a/eth_defi/terms_of_service/acceptance_message.py b/eth_defi/terms_of_service/acceptance_message.py new file mode 100644 index 00000000..afa8e3d8 --- /dev/null +++ b/eth_defi/terms_of_service/acceptance_message.py @@ -0,0 +1,63 @@ +"""The default terms of service message that is signed. + +- The terms of service itself is not signed as it is too big to fit to small input boxes of the wallet. + Instead, we sign a message that refers to the terms of service. + +- Uses EIP-151 + +- See `EthAccout.sign_message implementation `__. +""" +import datetime + +from eth_account.datastructures import SignedMessage +from eth_account.messages import encode_defunct, _hash_eip191_message +from eth_account.signers.local import LocalAccount + +DEFAULT_ACCEPTANCE_MESSAGE_TEMPLATE = """ +I read and agree on terms of service (version {version}) to use +smart contract software deployed on a blockchain. +The terms of service text was published {human_date} at {link}. +The unique identifier hash for this terms of service tgext was {hash}. +""".strip() + +INITIAL_ACCEPTANCE_MESSAGE = """ +I read and agree on terms of service (version 1) to use +smart contract software deployed on a blockchain. + +The terms of service text was published 10.1.2024 at https://example.com. +The unique identifier hash for this terms of service text was 0x0000000000000000000000000000000000000000. +""".strip() + + +def generate_acceptance_message(version: int, date: datetime.datetime, link: str, hash: bytes, template=DEFAULT_ACCEPTANCE_MESSAGE_TEMPLATE): + assert type(version) == int + assert type(link) == str + assert type(hash) == bytes + assert len(hash) == 32, "Must be 256-bit sha of terms of service file" + assert isinstance(date, datetime.datetime) + human_date = date.strftime("%Y-%m-%d") + return template.format(version=version, link=link, hash=hash.hex(), human_date=human_date) + + +def get_signing_hash(message: str) -> bytes: + assert type(message) == str + signable_message = encode_defunct(text=message) + hash = _hash_eip191_message(signable_message) + return hash + + +def sign_terms_of_service( + user: LocalAccount, + signable_message: str, +) -> tuple[bytes, bytes]: + """Sign terms of service for a local dev test account. + + :return: + Tuple (message hash, signed message) + """ + + assert isinstance(user, LocalAccount) + message_hash = get_signing_hash(signable_message) + signed_message = user.signHash(message_hash) + # import ipdb ; ipdb.set_trace() + return message_hash, signed_message.signature diff --git a/pyproject.toml b/pyproject.toml index 6438991e..6cccc3c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,9 +27,6 @@ Sponsor = "https://tradingstrategy.ai" [tool.poetry.dependencies] python = ">=3.10,<3.13" -# Only soft dependency in tests, but RTD complains -terms-of-service = {path = "contracts/terms-of-service", develop = true} - # https://github.com/apache/arrow/pull/35412 # Last checked 2023-07, still broken urllib3 = "<2" @@ -67,6 +64,11 @@ sphinxcontrib-htmlhelp = {version = "2.0.1", optional = true} # Version pindowns sphinxcontrib-serializinghtml = {version = "1.1.5", optional = true} # Version pindowns https://github.com/sphinx-doc/sphinxcontrib-serializinghtml/blob/master/CHANGES sphinxcontrib-qthelp = {version = "1.0.3", optional = true} # Version pindowns https://github.com/sphinx-doc/sphinxcontrib-qthelp/blob/master/CHANGES + +# Removed +# Only soft dependency in tests, but RTD complains +# terms-of-service = {path = "contracts/terms-of-service", develop = true} + [tool.poetry.dev-dependencies] pytest = "^7.4.3" pytest-mock = "^3.7.0" diff --git a/tests/enzyme/test_guard_enzyme_uniswap_v2.py b/tests/enzyme/test_guard_enzyme_uniswap_v2.py index b037441d..c2b505b6 100644 --- a/tests/enzyme/test_guard_enzyme_uniswap_v2.py +++ b/tests/enzyme/test_guard_enzyme_uniswap_v2.py @@ -15,11 +15,12 @@ from eth_account import Account from eth_account.signers.local import LocalAccount from eth_typing import HexAddress -from terms_of_service.acceptance_message import ( +from eth_defi.terms_of_service.acceptance_message import ( generate_acceptance_message, get_signing_hash, sign_terms_of_service, ) + from web3 import Web3 from web3.contract import Contract diff --git a/tests/enzyme/test_guard_enzyme_uniswap_v3.py b/tests/enzyme/test_guard_enzyme_uniswap_v3.py index 0e773f08..64a6151f 100644 --- a/tests/enzyme/test_guard_enzyme_uniswap_v3.py +++ b/tests/enzyme/test_guard_enzyme_uniswap_v3.py @@ -11,7 +11,7 @@ from eth_account import Account from eth_account.signers.local import LocalAccount from eth_typing import ChecksumAddress, HexAddress -from terms_of_service.acceptance_message import ( +from eth_defi.terms_of_service.acceptance_message import ( generate_acceptance_message, get_signing_hash, sign_terms_of_service, diff --git a/tests/rpc/test_forge_deploy.py b/tests/rpc/test_forge_deploy.py index 77aec721..6509282d 100644 --- a/tests/rpc/test_forge_deploy.py +++ b/tests/rpc/test_forge_deploy.py @@ -46,8 +46,7 @@ def web3(anvil: AnvilLaunch): @pytest.fixture def deployer(web3) -> LocalAccount: - """Create a priavte key with balance. - """ + """Create a priavte key with balance.""" _deployer = web3.eth.accounts[0] account: LocalAccount = Account.create() stash = web3.eth.get_balance(_deployer) diff --git a/tests/test_reorganisation_monitor_polygon.py b/tests/test_reorganisation_monitor_polygon.py index 8f3895c1..c68747d6 100644 --- a/tests/test_reorganisation_monitor_polygon.py +++ b/tests/test_reorganisation_monitor_polygon.py @@ -10,6 +10,7 @@ # Allow to override for a private node to run test faster JSON_RPC_POLYGON = os.environ.get("JSON_RPC_POLYGON", "https://polygon-rpc.com") + @pytest.mark.skipif(os.environ.get("CI") is not None, reason="Too flaky to run on Github because public Polygon endpoint is crap") def test_polygon_block_headers(): """Polygon block header data is downloaded."""