Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ venv
.log
__pycache__
.pytest_cache
.mypy_cache
slippage_project.log
1 change: 1 addition & 0 deletions contracts/erc20_abi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
ERC20 ABI contract
"""

erc20_abi = [
{
"constant": True,
Expand Down
3 changes: 1 addition & 2 deletions contracts/gpv2_settlement_abi.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
"""Contract ABI of the CoW Protocol settlement contract
"""
"""Contract ABI of the CoW Protocol settlement contract"""

gpv2_settlement_abi = [
{
Expand Down
141 changes: 80 additions & 61 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -77,118 +82,127 @@ 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
# pytest
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
Expand All @@ -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
8 changes: 4 additions & 4 deletions src/balanceof_imbalances.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
3 changes: 2 additions & 1 deletion src/constants.py
Original file line number Diff line number Diff line change
@@ -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(
Expand Down
1 change: 1 addition & 0 deletions src/helpers/helper_functions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
This file contains some auxiliary functions
"""

from __future__ import annotations
import sys
import os
Expand Down
14 changes: 7 additions & 7 deletions src/imbalances_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""

Expand Down
3 changes: 2 additions & 1 deletion tests/legacy/basic_test.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading