diff --git a/.gitignore b/.gitignore index b4ab0df..59e7d17 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ venv .log __pycache__ .pytest_cache +.mypy_cache slippage_project.log \ No newline at end of file diff --git a/contracts/erc20_abi.py b/contracts/erc20_abi.py index 9a0c632..e51ba84 100644 --- a/contracts/erc20_abi.py +++ b/contracts/erc20_abi.py @@ -1,6 +1,7 @@ """ ERC20 ABI contract """ + erc20_abi = [ { "constant": True, diff --git a/contracts/gpv2_settlement_abi.py b/contracts/gpv2_settlement_abi.py index c64e82a..f647686 100644 --- a/contracts/gpv2_settlement_abi.py +++ b/contracts/gpv2_settlement_abi.py @@ -1,5 +1,4 @@ -"""Contract ABI of the CoW Protocol settlement contract -""" +"""Contract ABI of the CoW Protocol settlement contract""" gpv2_settlement_abi = [ { diff --git a/requirements.txt b/requirements.txt index b844005..6092c57 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,69 +4,74 @@ # # pip-compile requirements.in # -aiohappyeyeballs==2.4.0 +aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.10.5 +aiohttp==3.12.15 # via # dune-client # web3 -aiosignal==1.3.1 +aiosignal==1.4.0 # via aiohttp annotated-types==0.7.0 # via pydantic -astroid==3.2.4 +astroid==3.3.11 # via pylint -attrs==24.2.0 +attrs==25.3.0 # via aiohttp -bitarray==2.9.2 +bitarray==3.6.1 # via eth-account -black==23.3.0 +black==25.1.0 # via -r requirements.in -certifi==2024.8.30 +certifi==2025.8.3 # via # moralis # requests -charset-normalizer==3.3.2 +charset-normalizer==3.4.3 # via requests -ckzg==2.0.1 +ckzg==2.1.1 # via eth-account -click==8.1.7 +click==8.2.1 # via black -cytoolz==0.12.3 +colorama==0.4.6 + # via + # click + # pylint + # pytest +cytoolz==1.0.1 # via eth-utils dataclasses-json==0.6.7 # via dune-client -deprecated==1.2.14 +deprecated==1.2.18 # via dune-client -dill==0.3.8 +dill==0.4.0 # via pylint -dune-client==1.7.5 +dune-client==1.7.10 # via -r requirements.in -eth-abi==5.1.0 +eth-abi==5.2.0 # via # eth-account # web3 -eth-account==0.13.3 +eth-account==0.13.7 # via web3 -eth-hash[pycryptodome]==0.7.0 +eth-hash[pycryptodome]==0.7.1 # via # eth-utils # web3 eth-keyfile==0.8.1 # via eth-account -eth-keys==0.5.1 +eth-keys==0.7.0 # via # eth-account # eth-keyfile -eth-rlp==2.1.0 +eth-rlp==2.2.0 # via eth-account -eth-typing==5.0.0 +eth-typing==5.2.1 # via # eth-abi # eth-keys # eth-utils # web3 -eth-utils==5.0.0 +eth-utils==5.3.0 # via # eth-abi # eth-account @@ -77,46 +82,45 @@ eth-utils==5.0.0 # web3 frozendict==2.3.10 # via moralis -frozenlist==1.4.1 +frozenlist==1.7.0 # via # aiohttp # aiosignal -greenlet==3.1.1 +greenlet==3.2.4 # via sqlalchemy -hexbytes==1.2.1 +hexbytes==1.3.1 # via # eth-account # eth-rlp - # eth-utils # web3 idna==3.10 # via # requests # yarl -iniconfig==2.0.0 +iniconfig==2.1.0 # via pytest -isort==5.13.2 +isort==6.0.1 # via pylint -marshmallow==3.22.0 +marshmallow==3.26.1 # via dataclasses-json mccabe==0.7.0 # via pylint moralis==0.1.49 # via -r requirements.in -multidict==6.1.0 +multidict==6.6.4 # via # aiohttp # yarl -mypy==1.4.1 +mypy==1.17.1 # via -r requirements.in -mypy-extensions==1.0.0 +mypy-extensions==1.1.0 # via # black # mypy # typing-inspect ndjson==0.3.1 # via dune-client -packaging==24.1 +packaging==25.0 # via # black # marshmallow @@ -124,71 +128,81 @@ packaging==24.1 parsimonious==0.10.0 # via eth-abi pathspec==0.12.1 - # via black -platformdirs==4.3.6 + # via + # black + # mypy +platformdirs==4.3.8 # via # black # pylint -pluggy==1.5.0 +pluggy==1.6.0 # via pytest -psycopg==3.2.3 +propcache==0.3.2 + # via + # aiohttp + # yarl +psycopg==3.2.9 # via -r requirements.in -pycryptodome==3.20.0 +pycryptodome==3.23.0 # via # eth-hash # eth-keyfile -pydantic==2.9.2 +pydantic==2.11.7 # via # eth-account + # eth-utils # web3 -pydantic-core==2.23.4 +pydantic-core==2.33.2 # via pydantic -pylint==3.2.5 +pygments==2.19.2 + # via pytest +pylint==3.3.8 # via -r requirements.in -pytest==7.4.0 +pytest==8.4.1 # via -r requirements.in python-dateutil==2.9.0.post0 # via # dune-client # moralis -python-dotenv==1.0.0 +python-dotenv==1.1.1 # via -r requirements.in pyunormalize==16.0.0 # via web3 -regex==2024.9.11 +regex==2025.7.34 # via parsimonious -requests==2.31.0 +requests==2.32.4 # via # -r requirements.in # dune-client # web3 -rlp==4.0.1 +rlp==4.1.0 # via # eth-account # eth-rlp -six==1.16.0 +six==1.17.0 # via python-dateutil -sqlalchemy==2.0.28 +sqlalchemy==2.0.43 # via -r requirements.in -tomlkit==0.13.2 +tomlkit==0.13.3 # via pylint -toolz==0.12.1 +toolz==1.0.0 # via cytoolz -types-deprecated==1.2.9.20240311 +types-deprecated==1.2.15.20250304 # via dune-client -types-python-dateutil==2.9.0.20240906 +types-python-dateutil==2.9.0.20250809 # via dune-client -types-pyyaml==6.0.12.20240917 +types-pyyaml==6.0.12.20250809 # via dune-client -types-requests==2.32.0.20240914 +types-requests==2.32.4.20250809 # via # -r requirements.in # dune-client # web3 -types-setuptools==75.1.0.20240917 +types-setuptools==80.9.0.20250809 # via dune-client -typing-extensions==4.12.2 +typing-extensions==4.14.1 # via + # aiosignal # eth-typing # moralis # mypy @@ -197,19 +211,24 @@ typing-extensions==4.12.2 # pydantic-core # sqlalchemy # typing-inspect + # typing-inspection # web3 typing-inspect==0.9.0 # via dataclasses-json -urllib3==2.2.3 +typing-inspection==0.4.1 + # via pydantic +tzdata==2025.2 + # via psycopg +urllib3==2.5.0 # via # moralis # requests # types-requests -web3==7.0.0 +web3==7.13.0 # via -r requirements.in -websockets==13.1 +websockets==15.0.1 # via web3 -wrapt==1.16.0 +wrapt==1.17.3 # via deprecated -yarl==1.11.1 +yarl==1.20.1 # via aiohttp diff --git a/src/balanceof_imbalances.py b/src/balanceof_imbalances.py index 53530ac..8406083 100644 --- a/src/balanceof_imbalances.py +++ b/src/balanceof_imbalances.py @@ -65,10 +65,10 @@ def get_balances( ) -> Dict[ChecksumAddress, Optional[int]]: """Get balances for all tokens at the given block number.""" balances: Dict[ChecksumAddress, Optional[int]] = {} - balances[ - self.web3.to_checksum_address(NATIVE_ETH_TOKEN_ADDRESS) - ] = self.get_eth_balance( - self.web3.to_checksum_address(SETTLEMENT_CONTRACT_ADDRESS), block_number + balances[self.web3.to_checksum_address(NATIVE_ETH_TOKEN_ADDRESS)] = ( + self.get_eth_balance( + self.web3.to_checksum_address(SETTLEMENT_CONTRACT_ADDRESS), block_number + ) ) for token_address in token_addresses: diff --git a/src/constants.py b/src/constants.py index 215f8ca..25e029e 100644 --- a/src/constants.py +++ b/src/constants.py @@ -1,4 +1,5 @@ -""" Constants used for the token imbalances project """ +"""Constants used for the token imbalances project""" + from web3 import Web3 SETTLEMENT_CONTRACT_ADDRESS = Web3.to_checksum_address( diff --git a/src/helpers/helper_functions.py b/src/helpers/helper_functions.py index 522a66c..35468d1 100644 --- a/src/helpers/helper_functions.py +++ b/src/helpers/helper_functions.py @@ -1,6 +1,7 @@ """ This file contains some auxiliary functions """ + from __future__ import annotations import sys import os diff --git a/src/imbalances_script.py b/src/imbalances_script.py index baf276a..c4e8100 100644 --- a/src/imbalances_script.py +++ b/src/imbalances_script.py @@ -3,22 +3,22 @@ Steps for computing token imbalances: 1. Get transaction receipt via tx hash -> get_transaction_receipt() -2. Obtain the transaction trace and extract actions from trace to identify actions +2. Obtain the transaction trace and extract actions from trace to identify actions related to native ETH transfers -> get_transaction_trace() and extract_actions() -3. Calculate ETH imbalance via actions by identifying transfers in +3. Calculate ETH imbalance via actions by identifying transfers in and out of a contract address -> calculate_native_eth_imbalance() -4. Extract and categorize relevant events (such as ERC20 transfers, WETH withdrawals, +4. Extract and categorize relevant events (such as ERC20 transfers, WETH withdrawals, and sDAI transactions) from the transaction receipt. -> extract_events() 5. Process each event by first decoding it to retrieve event details, i.e. to_address, from_address and transfer value -> decode_event() -6. If to_address or from_address match the contract address parameter, update inflows/outflows by +6. If to_address or from_address match the contract address parameter, update inflows/outflows by adding the transfer value to existing inflow/outflow for the token addresses. 7. Returning to calculate_imbalances(), which finds the imbalance for all token addresses using inflow-outflow. -8. If actions are not None, it denotes an ETH transfer event, which involves reducing WETH - withdrawal amount- > update_weth_imbalance(). The ETH imbalance is also calculated +8. If actions are not None, it denotes an ETH transfer event, which involves reducing WETH + withdrawal amount- > update_weth_imbalance(). The ETH imbalance is also calculated via -> update_native_eth_imbalance(). -9. update_sdai_imbalance() is called in each iteration and only completes if there is an SDAI +9. update_sdai_imbalance() is called in each iteration and only completes if there is an SDAI transfer involved which has special handling for its events. """ diff --git a/tests/legacy/basic_test.py b/tests/legacy/basic_test.py index b01ca9e..a4544f5 100644 --- a/tests/legacy/basic_test.py +++ b/tests/legacy/basic_test.py @@ -1,4 +1,5 @@ -""" Runs a basic test for raw imbalance calculation edge-cases. """ +"""Runs a basic test for raw imbalance calculation edge-cases.""" + import os from dotenv import load_dotenv import pytest