yearn-treasury 0.1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of yearn-treasury might be problematic. Click here for more details.
- yearn_treasury-0.1.5/MANIFEST.in +1 -0
- yearn_treasury-0.1.5/PKG-INFO +85 -0
- yearn_treasury-0.1.5/README.md +60 -0
- yearn_treasury-0.1.5/pyproject.toml +57 -0
- yearn_treasury-0.1.5/setup.cfg +4 -0
- yearn_treasury-0.1.5/setup.py +221 -0
- yearn_treasury-0.1.5/yearn_treasury/__init__.py +20 -0
- yearn_treasury-0.1.5/yearn_treasury/_db.py +51 -0
- yearn_treasury-0.1.5/yearn_treasury/_ens.py +31 -0
- yearn_treasury-0.1.5/yearn_treasury/_logging.py +43 -0
- yearn_treasury-0.1.5/yearn_treasury/address_labels.yaml +39 -0
- yearn_treasury-0.1.5/yearn_treasury/budget/__init__.py +6 -0
- yearn_treasury-0.1.5/yearn_treasury/budget/_request.py +44 -0
- yearn_treasury-0.1.5/yearn_treasury/budget/_requests.py +96 -0
- yearn_treasury-0.1.5/yearn_treasury/constants.py +92 -0
- yearn_treasury-0.1.5/yearn_treasury/main.py +176 -0
- yearn_treasury-0.1.5/yearn_treasury/py.typed +1 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/__init__.py +20 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/constants.py +17 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/cost_of_revenue/__init__.py +1 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/cost_of_revenue/gas.py +66 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/cost_of_revenue/match_on_hash.yaml +12 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/expense/__init__.py +4 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/expense/general.py +13 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/expense/infrastructure.py +47 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/expense/match_on_hash.yaml +48 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/expense/match_on_to_address.yaml +7 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/expense/people.py +84 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/expense/security.py +147 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/__init__.py +8 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/general.py +11 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/maker.py +92 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/passthru.py +310 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/staking.py +102 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/__init__.py +25 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/_skip_tokens.py +9 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/aave.py +69 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/auctions.py +31 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/compound.py +58 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/conversion_factory.py +21 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/cowswap.py +87 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/curve.py +176 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/gearbox.py +37 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/iearn.py +43 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/otc.py +58 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/pooltogether.py +23 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/synthetix.py +10 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/uniswap.py +294 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/unwrapper.py +17 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/vaults.py +264 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/woofy.py +80 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/yfi.py +111 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/swaps/yla.py +28 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/unit.py +40 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/weth.py +48 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/ignore/ygov.py +16 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/__init__.py +7 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/boost.py +49 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/bugs.py +81 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/donations.py +43 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/dyfi.py +29 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/events.py +21 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/match_on_hash.yaml +43 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/match_on_to_address.yaml +8 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/misc.py +49 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_expense/revshare.py +20 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_income/__init__.py +2 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_income/airdrops.py +30 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_income/match_on_hash.yaml +21 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/other_income/misc.py +80 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/revenue/__init__.py +6 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/revenue/bribes.py +26 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/revenue/farming.py +56 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/revenue/keepcoins.py +63 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/revenue/match_on_hash.yaml +4 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/revenue/seasolver.py +23 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/revenue/vaults.py +172 -0
- yearn_treasury-0.1.5/yearn_treasury/rules/revenue/yteams.py +17 -0
- yearn_treasury-0.1.5/yearn_treasury/shitcoins.py +143 -0
- yearn_treasury-0.1.5/yearn_treasury/vaults.py +50 -0
- yearn_treasury-0.1.5/yearn_treasury/wallets.yaml +54 -0
- yearn_treasury-0.1.5/yearn_treasury/yteams.py +208 -0
- yearn_treasury-0.1.5/yearn_treasury.egg-info/PKG-INFO +85 -0
- yearn_treasury-0.1.5/yearn_treasury.egg-info/SOURCES.txt +87 -0
- yearn_treasury-0.1.5/yearn_treasury.egg-info/dependency_links.txt +1 -0
- yearn_treasury-0.1.5/yearn_treasury.egg-info/entry_points.txt +2 -0
- yearn_treasury-0.1.5/yearn_treasury.egg-info/not-zip-safe +1 -0
- yearn_treasury-0.1.5/yearn_treasury.egg-info/requires.txt +1 -0
- yearn_treasury-0.1.5/yearn_treasury.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include yearn_treasury *.yaml
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yearn_treasury
|
|
3
|
+
Version: 0.1.5
|
|
4
|
+
Summary: This WIP library runs the eth-portfolio and dao-treasury exporters for the Yearn Finance treasury.
|
|
5
|
+
Classifier: Development Status :: 3 - Alpha
|
|
6
|
+
Classifier: Intended Audience :: Developers
|
|
7
|
+
Classifier: Intended Audience :: Science/Research
|
|
8
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
16
|
+
Requires-Python: >=3.10,<3.13
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
Requires-Dist: dao-treasury==0.1.7
|
|
19
|
+
Dynamic: classifier
|
|
20
|
+
Dynamic: description
|
|
21
|
+
Dynamic: description-content-type
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: requires-python
|
|
24
|
+
Dynamic: summary
|
|
25
|
+
|
|
26
|
+
This WIP library runs the [dao-treasury](https://github.com/BobTheBuidler/dao-treasury) exporter for the [Yearn Finance](https://yearn.fi/) treasury.
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
- **pip:**
|
|
31
|
+
```bash
|
|
32
|
+
pip install yearn-treasury
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
- **From Source:**
|
|
36
|
+
```bash
|
|
37
|
+
git clone https://github.com/BobTheBuidler/yearn-treasury
|
|
38
|
+
cd yearn-treasury
|
|
39
|
+
poetry install
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Requirements
|
|
43
|
+
- Python 3.10 or higher.
|
|
44
|
+
- At least 16GB of RAM.
|
|
45
|
+
- All dependencies installed as specified in the project’s pyproject.toml file.
|
|
46
|
+
|
|
47
|
+
## Prerequisites
|
|
48
|
+
|
|
49
|
+
- First, you will need to bring your own archive node. This can be one you run yourself, or one from one of the common providers (Tenderly, Alchemy, QuickNode, etc.). Your archive node must have tracing enabled (free-tier Alchemy nodes do not support this option).
|
|
50
|
+
- You must configure a [brownie network](https://eth-brownie.readthedocs.io/en/stable/network-management.html) to use your RPC.
|
|
51
|
+
- You will need an auth token for [Etherscan](https://etherscan.io/)'s API. Follow their [guide](https://docs.etherscan.io/etherscan-v2/getting-an-api-key) to get your key, and set env var `ETHERSCAN_TOKEN` with its value.
|
|
52
|
+
- You'll also need [Docker](https://www.docker.com/get-started/) installed on your system. If on MacOS, you will need to leave Docker Desktop open while Yearn Treasury is running.
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
Run the treasury export tool:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# For pip installations:
|
|
60
|
+
yearn-treasury --network mainnet --interval 12h
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
For local development (from source installation), use:
|
|
64
|
+
```bash
|
|
65
|
+
poetry run yearn-treasury --network mainnet --interval 12h
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**CLI Options:**
|
|
69
|
+
- `--network`: The id of the brownie network the exporter will connect to (default: mainnet)
|
|
70
|
+
- `--interval`: The time interval between each data snapshot (default: 12h)
|
|
71
|
+
- `--daemon`: Run the export process in the background (default: False) (NOTE: currently unsupported)
|
|
72
|
+
- `--grafana-port`: Set the port for the Grafana dashboard where you can view data (default: 3004)
|
|
73
|
+
- `--renderer-port`: Set the port for the report rendering service (default: 8080)
|
|
74
|
+
- `--victoria-port`: Set the port for the Victoria metrics reporting endpoint (default: 8430)
|
|
75
|
+
|
|
76
|
+
After running the command, the export script will run continuously until you close your terminal.
|
|
77
|
+
To access the dashboard, open your browser and navigate to [http://localhost:3004](http://localhost:3004) for the [dao-treasury](https://github.com/BobTheBuidler/dao-treasury) dashboard.
|
|
78
|
+
|
|
79
|
+
Enjoy!
|
|
80
|
+
|
|
81
|
+
## Screenshots
|
|
82
|
+
|
|
83
|
+
#### [Transactions Dashboard](https://bobthebuidler.github.io/yearn-treasury/transactions.html)
|
|
84
|
+
|
|
85
|
+

|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
This WIP library runs the [dao-treasury](https://github.com/BobTheBuidler/dao-treasury) exporter for the [Yearn Finance](https://yearn.fi/) treasury.
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
- **pip:**
|
|
6
|
+
```bash
|
|
7
|
+
pip install yearn-treasury
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
- **From Source:**
|
|
11
|
+
```bash
|
|
12
|
+
git clone https://github.com/BobTheBuidler/yearn-treasury
|
|
13
|
+
cd yearn-treasury
|
|
14
|
+
poetry install
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Requirements
|
|
18
|
+
- Python 3.10 or higher.
|
|
19
|
+
- At least 16GB of RAM.
|
|
20
|
+
- All dependencies installed as specified in the project’s pyproject.toml file.
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
- First, you will need to bring your own archive node. This can be one you run yourself, or one from one of the common providers (Tenderly, Alchemy, QuickNode, etc.). Your archive node must have tracing enabled (free-tier Alchemy nodes do not support this option).
|
|
25
|
+
- You must configure a [brownie network](https://eth-brownie.readthedocs.io/en/stable/network-management.html) to use your RPC.
|
|
26
|
+
- You will need an auth token for [Etherscan](https://etherscan.io/)'s API. Follow their [guide](https://docs.etherscan.io/etherscan-v2/getting-an-api-key) to get your key, and set env var `ETHERSCAN_TOKEN` with its value.
|
|
27
|
+
- You'll also need [Docker](https://www.docker.com/get-started/) installed on your system. If on MacOS, you will need to leave Docker Desktop open while Yearn Treasury is running.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
Run the treasury export tool:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# For pip installations:
|
|
35
|
+
yearn-treasury --network mainnet --interval 12h
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For local development (from source installation), use:
|
|
39
|
+
```bash
|
|
40
|
+
poetry run yearn-treasury --network mainnet --interval 12h
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**CLI Options:**
|
|
44
|
+
- `--network`: The id of the brownie network the exporter will connect to (default: mainnet)
|
|
45
|
+
- `--interval`: The time interval between each data snapshot (default: 12h)
|
|
46
|
+
- `--daemon`: Run the export process in the background (default: False) (NOTE: currently unsupported)
|
|
47
|
+
- `--grafana-port`: Set the port for the Grafana dashboard where you can view data (default: 3004)
|
|
48
|
+
- `--renderer-port`: Set the port for the report rendering service (default: 8080)
|
|
49
|
+
- `--victoria-port`: Set the port for the Victoria metrics reporting endpoint (default: 8430)
|
|
50
|
+
|
|
51
|
+
After running the command, the export script will run continuously until you close your terminal.
|
|
52
|
+
To access the dashboard, open your browser and navigate to [http://localhost:3004](http://localhost:3004) for the [dao-treasury](https://github.com/BobTheBuidler/dao-treasury) dashboard.
|
|
53
|
+
|
|
54
|
+
Enjoy!
|
|
55
|
+
|
|
56
|
+
## Screenshots
|
|
57
|
+
|
|
58
|
+
#### [Transactions Dashboard](https://bobthebuidler.github.io/yearn-treasury/transactions.html)
|
|
59
|
+
|
|
60
|
+

|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
[tool.poetry]
|
|
2
|
+
name = "yearn-treasury"
|
|
3
|
+
version = "0.1.5"
|
|
4
|
+
description = "This WIP library runs the eth-portfolio and dao-treasury exporters for the Yearn Finance treasury."
|
|
5
|
+
authors = ["Bob The Buidler <you@example.com>"]
|
|
6
|
+
packages = [{ include = "yearn_treasury/*" }]
|
|
7
|
+
|
|
8
|
+
[build-system]
|
|
9
|
+
requires = [
|
|
10
|
+
"setuptools",
|
|
11
|
+
"wheel",
|
|
12
|
+
"mypy[mypyc]==1.19.0",
|
|
13
|
+
"tomli>=2.0.0; python_version < '3.11'",
|
|
14
|
+
"types-requests",
|
|
15
|
+
"dao-treasury==0.1.7; platform_system == 'Linux' and platform_machine != 'i686'",
|
|
16
|
+
"eth-brownie==1.22.0.dev0; platform_system == 'Linux'",
|
|
17
|
+
"eth-typing==5.2.1",
|
|
18
|
+
]
|
|
19
|
+
build-backend = "setuptools.build_meta"
|
|
20
|
+
|
|
21
|
+
[tool.poetry.scripts]
|
|
22
|
+
yearn-treasury = "yearn_treasury.main:main"
|
|
23
|
+
|
|
24
|
+
[tool.poetry.dependencies]
|
|
25
|
+
python = ">=3.10,<3.13"
|
|
26
|
+
dao-treasury = "==0.1.7"
|
|
27
|
+
|
|
28
|
+
[tool.poetry.group.dev.dependencies]
|
|
29
|
+
mypy = "1.19.0"
|
|
30
|
+
types-requests = "*"
|
|
31
|
+
|
|
32
|
+
[tool.poetry.group.docs.dependencies]
|
|
33
|
+
sphinx = "*"
|
|
34
|
+
sphinx-rtd-theme = "*"
|
|
35
|
+
myst-parser = "*"
|
|
36
|
+
|
|
37
|
+
[tool.mypy]
|
|
38
|
+
exclude = ["build/","cache/","env/", "tests/", "setup.py"]
|
|
39
|
+
ignore_missing_imports = true
|
|
40
|
+
check_untyped_defs = true
|
|
41
|
+
|
|
42
|
+
[tool.black]
|
|
43
|
+
line-length = 100
|
|
44
|
+
target-version = ['py310']
|
|
45
|
+
include = '\.pyi?$'
|
|
46
|
+
exclude = '''
|
|
47
|
+
/(
|
|
48
|
+
\.git
|
|
49
|
+
| \.hypothesis
|
|
50
|
+
| \.mypy_cache
|
|
51
|
+
| \.pytest_cache
|
|
52
|
+
| \.venv
|
|
53
|
+
| cache
|
|
54
|
+
| dist
|
|
55
|
+
| env
|
|
56
|
+
)/
|
|
57
|
+
'''
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from setuptools import find_packages, setup
|
|
3
|
+
|
|
4
|
+
try:
|
|
5
|
+
from mypyc.build import mypycify
|
|
6
|
+
except ImportError:
|
|
7
|
+
ext_modules = []
|
|
8
|
+
else:
|
|
9
|
+
ext_modules = mypycify(
|
|
10
|
+
[
|
|
11
|
+
"yearn_treasury/budget",
|
|
12
|
+
"yearn_treasury/rules/constants.py",
|
|
13
|
+
"yearn_treasury/rules/cost_of_revenue/gas.py",
|
|
14
|
+
"yearn_treasury/rules/expense",
|
|
15
|
+
# "yearn_treasury/rules/ignore",
|
|
16
|
+
"yearn_treasury/rules/ignore/swaps/conversion_factory.py",
|
|
17
|
+
"yearn_treasury/rules/ignore/swaps/auctions.py",
|
|
18
|
+
# "yearn_treasury/rules/ignore/swaps/curve.py", enable with brownie 1.22.0
|
|
19
|
+
"yearn_treasury/rules/ignore/swaps/gearbox.py",
|
|
20
|
+
"yearn_treasury/rules/ignore/swaps/iearn.py",
|
|
21
|
+
"yearn_treasury/rules/ignore/swaps/otc.py",
|
|
22
|
+
"yearn_treasury/rules/ignore/swaps/pooltogether.py",
|
|
23
|
+
"yearn_treasury/rules/ignore/swaps/synthetix.py",
|
|
24
|
+
"yearn_treasury/rules/ignore/swaps/unwrapper.py",
|
|
25
|
+
"yearn_treasury/rules/ignore/swaps/vaults.py",
|
|
26
|
+
"yearn_treasury/rules/ignore/swaps/woofy.py",
|
|
27
|
+
"yearn_treasury/rules/ignore/swaps/yfi.py",
|
|
28
|
+
"yearn_treasury/rules/ignore/swaps/yla.py",
|
|
29
|
+
"yearn_treasury/rules/ignore/general.py",
|
|
30
|
+
"yearn_treasury/rules/ignore/unit.py",
|
|
31
|
+
"yearn_treasury/rules/ignore/weth.py",
|
|
32
|
+
"yearn_treasury/rules/ignore/ygov.py",
|
|
33
|
+
"yearn_treasury/rules/other_expense",
|
|
34
|
+
"yearn_treasury/rules/other_income",
|
|
35
|
+
"yearn_treasury/rules/revenue/bribes.py",
|
|
36
|
+
"yearn_treasury/rules/revenue/farming.py",
|
|
37
|
+
"yearn_treasury/rules/revenue/keepcoins.py",
|
|
38
|
+
"yearn_treasury/rules/revenue/seasolver.py",
|
|
39
|
+
# "yearn_treasury/rules/revenue/vaults.py", enable with brownie 1.22.0
|
|
40
|
+
"yearn_treasury/rules/revenue/yteams.py",
|
|
41
|
+
"yearn_treasury/_db.py",
|
|
42
|
+
"yearn_treasury/_ens.py",
|
|
43
|
+
"yearn_treasury/_logging.py",
|
|
44
|
+
"yearn_treasury/vaults.py",
|
|
45
|
+
"--strict",
|
|
46
|
+
"--pretty",
|
|
47
|
+
"--disable-error-code=unused-ignore",
|
|
48
|
+
"--disable-error-code=union-attr",
|
|
49
|
+
"--disable-error-code=no-any-return",
|
|
50
|
+
"--disable-error-code=untyped-decorator",
|
|
51
|
+
"--disable-error-code=misc", # TODO: drop support for 32bit systems
|
|
52
|
+
],
|
|
53
|
+
group_name="yearn_treasury",
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
import tomllib # Python 3.11+
|
|
59
|
+
except ModuleNotFoundError:
|
|
60
|
+
import tomli as tomllib # Older Python
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
with Path("pyproject.toml").open("rb") as f:
|
|
64
|
+
pyproject_data = tomllib.load(f)
|
|
65
|
+
poetry_config = pyproject_data["tool"]["poetry"]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def poetry_dependencies_to_install_requires(poetry_deps):
|
|
69
|
+
"""
|
|
70
|
+
Reads [tool.poetry.dependencies] in pyproject.toml and converts them
|
|
71
|
+
into a list of valid PEP 508–compatible dependency strings for setuptools.
|
|
72
|
+
"""
|
|
73
|
+
if not poetry_deps:
|
|
74
|
+
return []
|
|
75
|
+
|
|
76
|
+
install_requires = []
|
|
77
|
+
for name, spec in poetry_deps.items():
|
|
78
|
+
# Poetry often puts a 'python' key for the project's own Python requirement:
|
|
79
|
+
# [tool.poetry.dependencies]
|
|
80
|
+
# python = "^3.7"
|
|
81
|
+
# We'll skip that, because it's not an actual package dep.
|
|
82
|
+
if name.lower() == "python":
|
|
83
|
+
continue
|
|
84
|
+
|
|
85
|
+
if pep508_str := poetry_dep_to_pep508_string(name, spec):
|
|
86
|
+
install_requires.append(pep508_str)
|
|
87
|
+
|
|
88
|
+
return install_requires
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def poetry_dep_to_pep508_string(package_name, spec):
|
|
92
|
+
"""
|
|
93
|
+
Convert a Poetry-style dependency spec into a single string usable by
|
|
94
|
+
setuptools (PEP 508). Handles "version", "markers", "extras", and "python".
|
|
95
|
+
|
|
96
|
+
Examples of 'spec':
|
|
97
|
+
">=1.0" (just a string)
|
|
98
|
+
{ version=">=1.0,<2.0" }
|
|
99
|
+
{ version=">=1.0", markers="python_version < '3.9'", python=">=3.7,<3.10" }
|
|
100
|
+
{ extras=["some_extra"], version=">=2.0" }
|
|
101
|
+
"""
|
|
102
|
+
if isinstance(spec, str):
|
|
103
|
+
# e.g. ">=1.0" or "*"
|
|
104
|
+
if spec.strip() == "*":
|
|
105
|
+
# "*" means "any version," so just return the package name alone.
|
|
106
|
+
return package_name
|
|
107
|
+
return f"{package_name}{format_version_part(spec)}"
|
|
108
|
+
|
|
109
|
+
if isinstance(spec, dict):
|
|
110
|
+
return poetry_dep_dict_to_pep508_string(spec, package_name)
|
|
111
|
+
# If it's unrecognized, just return the package name as a fallback:
|
|
112
|
+
return str(package_name)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# TODO Rename this here and in `poetry_dep_to_pep508_string`
|
|
116
|
+
def poetry_dep_dict_to_pep508_string(spec, package_name):
|
|
117
|
+
version_part = spec.get("version", "")
|
|
118
|
+
markers_part = spec.get("markers", "")
|
|
119
|
+
python_part = spec.get("python", "")
|
|
120
|
+
extras = spec.get("extras", [])
|
|
121
|
+
|
|
122
|
+
# If version == "*", treat it as no version
|
|
123
|
+
if version_part.strip() == "*":
|
|
124
|
+
version_part = ""
|
|
125
|
+
|
|
126
|
+
# Turn extras into a "pkg[extra1,extra2]" form if there are any
|
|
127
|
+
pkg_with_extras = f"{package_name}[{','.join(extras)}]" if extras else package_name
|
|
128
|
+
# Build up a Python-version marker if "python" is given
|
|
129
|
+
# e.g., python=">=3.7,<3.9" => "python_version >= '3.7' and python_version < '3.9'"
|
|
130
|
+
py_marker = convert_python_spec_to_marker(python_part) if python_part else ""
|
|
131
|
+
|
|
132
|
+
# Combine any existing spec markers with this python marker.
|
|
133
|
+
# If both exist, we'll join them with " and ".
|
|
134
|
+
combined_markers = combine_markers(markers_part, py_marker)
|
|
135
|
+
|
|
136
|
+
# Build final requirement:
|
|
137
|
+
# pkg[extras]>1.0 ; (python_version >= '3.7' and <some_other_marker>)
|
|
138
|
+
# If there's no combined_markers, we omit the semicolon part entirely.
|
|
139
|
+
requirement = pkg_with_extras + format_version_part(version_part)
|
|
140
|
+
if combined_markers:
|
|
141
|
+
requirement += f" ; {combined_markers}"
|
|
142
|
+
|
|
143
|
+
return requirement
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def format_version_part(version_spec):
|
|
147
|
+
"""
|
|
148
|
+
If version_spec starts with an operator, prepend a space
|
|
149
|
+
so it looks like "mypkg >=1.0.0" instead of "mypkg>=1.0.0".
|
|
150
|
+
"""
|
|
151
|
+
return f" {version_spec}" if version_spec else ""
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def convert_python_spec_to_marker(python_spec):
|
|
155
|
+
"""
|
|
156
|
+
Very basic converter for something like ">=3.7,<3.10"
|
|
157
|
+
into "python_version >= '3.7' and python_version < '3.10'".
|
|
158
|
+
It doesn't handle ^ or ~ operators. If needed, expand this logic.
|
|
159
|
+
"""
|
|
160
|
+
if not python_spec:
|
|
161
|
+
return ""
|
|
162
|
+
|
|
163
|
+
parts = [p.strip() for p in python_spec.split(",")]
|
|
164
|
+
marker_clauses = []
|
|
165
|
+
for part in parts:
|
|
166
|
+
for op in [">=", "<=", "==", "!=", ">", "<"]:
|
|
167
|
+
if part.startswith(op):
|
|
168
|
+
version_val = part[len(op) :].strip()
|
|
169
|
+
marker_clauses.append(f"python_version {op} '{version_val}'")
|
|
170
|
+
break
|
|
171
|
+
else:
|
|
172
|
+
# If we didn't break, we didn't find a known operator
|
|
173
|
+
# fallback to "=="
|
|
174
|
+
if part:
|
|
175
|
+
marker_clauses.append(f"python_version == '{part}'")
|
|
176
|
+
|
|
177
|
+
return " and ".join(marker_clauses)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def combine_markers(a, b):
|
|
181
|
+
"""
|
|
182
|
+
Combine two marker expressions (a and b) with "and" if both are non-empty.
|
|
183
|
+
If one is empty, return the other.
|
|
184
|
+
"""
|
|
185
|
+
a = a.strip()
|
|
186
|
+
b = b.strip()
|
|
187
|
+
return f"({a}) and ({b})" if a and b else a or b
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
with open("README.md", "r", encoding="utf-8") as readme:
|
|
191
|
+
long_description = readme.read()
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
setup(
|
|
195
|
+
name=poetry_config["name"].replace("-", "_"),
|
|
196
|
+
version=poetry_config["version"],
|
|
197
|
+
python_requires=">=3.10,<3.13",
|
|
198
|
+
packages=find_packages(),
|
|
199
|
+
package_data={"yearn_treasury": ["py.typed"]},
|
|
200
|
+
include_package_data=True,
|
|
201
|
+
description=poetry_config["description"],
|
|
202
|
+
long_description=long_description,
|
|
203
|
+
long_description_content_type="text/markdown",
|
|
204
|
+
entry_points={"console_scripts": ["yearn-treasury=yearn_treasury.main:main"]},
|
|
205
|
+
install_requires=poetry_dependencies_to_install_requires(poetry_config["dependencies"]),
|
|
206
|
+
ext_modules=ext_modules,
|
|
207
|
+
zip_safe=False,
|
|
208
|
+
classifiers=[
|
|
209
|
+
"Development Status :: 3 - Alpha",
|
|
210
|
+
"Intended Audience :: Developers",
|
|
211
|
+
"Intended Audience :: Science/Research",
|
|
212
|
+
"Intended Audience :: End Users/Desktop",
|
|
213
|
+
"Programming Language :: Python :: 3",
|
|
214
|
+
"Programming Language :: Python :: 3.10",
|
|
215
|
+
"Programming Language :: Python :: 3.11",
|
|
216
|
+
"Programming Language :: Python :: 3.12",
|
|
217
|
+
"Programming Language :: Python :: Implementation :: CPython",
|
|
218
|
+
"Operating System :: OS Independent",
|
|
219
|
+
"Topic :: Software Development :: Libraries",
|
|
220
|
+
],
|
|
221
|
+
)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
3
|
+
from yearn_treasury import budget
|
|
4
|
+
from yearn_treasury._db import prepare_db
|
|
5
|
+
from yearn_treasury._logging import setup_eth_portfolio_logging
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
prepare_db()
|
|
9
|
+
setup_eth_portfolio_logging()
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
warnings.filterwarnings(
|
|
13
|
+
"ignore",
|
|
14
|
+
message=".Event log does not contain enough topics for the given ABI.",
|
|
15
|
+
category=UserWarning,
|
|
16
|
+
module="brownie.network.event",
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = ["budget"]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Database labeling utility for Yearn Treasury.
|
|
3
|
+
|
|
4
|
+
This module provides a helper function to set up address nicknames
|
|
5
|
+
in the database, mapping key Yearn Treasury addresses to human-readable
|
|
6
|
+
labels. It is used during database preparation to ensure that wallet
|
|
7
|
+
addresses are clearly labeled in analytics and reporting.
|
|
8
|
+
|
|
9
|
+
When Yearn Treasury is imported, this module maps important addresses
|
|
10
|
+
to descriptive nicknames within the DAO Treasury database entity system
|
|
11
|
+
for improved data clarity and prettification of reports.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# mypy: disable-error-code="arg-type"
|
|
15
|
+
import time
|
|
16
|
+
|
|
17
|
+
import dao_treasury._docker
|
|
18
|
+
from dao_treasury.db import Address, init_db
|
|
19
|
+
from y import Network
|
|
20
|
+
from y.constants import CHAINID
|
|
21
|
+
|
|
22
|
+
from yearn_treasury import constants
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def prepare_db() -> None:
|
|
26
|
+
"""
|
|
27
|
+
Set up address nicknames in the Yearn Treasury database.
|
|
28
|
+
|
|
29
|
+
Maps key Yearn Treasury addresses to human-readable labels for improved
|
|
30
|
+
clarity in analytics and reporting. This function is typically called
|
|
31
|
+
during database preparation to ensure wallet addresses are labeled
|
|
32
|
+
within the DAO Treasury database entity system.
|
|
33
|
+
"""
|
|
34
|
+
# We need to start the postgres container earlier than dao-treasury does
|
|
35
|
+
dao_treasury._docker.up("postgres")
|
|
36
|
+
|
|
37
|
+
time.sleep(5)
|
|
38
|
+
|
|
39
|
+
init_db()
|
|
40
|
+
|
|
41
|
+
chad = {Network.Mainnet: "y", Network.Fantom: "f"}[CHAINID] # type: ignore [index]
|
|
42
|
+
|
|
43
|
+
labels = {
|
|
44
|
+
constants.TREASURY_MULTISIG: "Yearn Treasury",
|
|
45
|
+
constants.YCHAD_MULTISIG: f"Yearn {chad}Chad Multisig",
|
|
46
|
+
# constants.STRATEGIST_MULTISIG: "Yearn Strategist Multisig",
|
|
47
|
+
# This wallet is an EOA that has been used to assist in bridging tokens across chains.
|
|
48
|
+
"0x5FcdC32DfC361a32e9d5AB9A384b890C62D0b8AC": "Bridge Assistooor EOA",
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
Address.set_nicknames(labels)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ENS resolver and event topic utilities for Yearn Treasury.
|
|
3
|
+
|
|
4
|
+
This module defines the ENS resolver contract and event topic set
|
|
5
|
+
used for dynamic vault discovery and event processing. It supports
|
|
6
|
+
vault mapping and analytics by enabling on-chain lookups and event
|
|
7
|
+
filtering for Yearn vaults.
|
|
8
|
+
|
|
9
|
+
Key Responsibilities:
|
|
10
|
+
- Provide the ENS resolver contract for vault registry lookups.
|
|
11
|
+
- Construct event topic sets for AddressChanged events.
|
|
12
|
+
- Used by vault discovery, analytics, and reporting modules.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import Final
|
|
16
|
+
|
|
17
|
+
from brownie import web3
|
|
18
|
+
from web3._utils.abi import filter_by_name
|
|
19
|
+
from web3._utils.events import construct_event_topic_set
|
|
20
|
+
from y import Contract
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
resolver: Final[Contract] = Contract("0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41")
|
|
24
|
+
|
|
25
|
+
topics: Final = construct_event_topic_set(
|
|
26
|
+
filter_by_name("AddressChanged", resolver.abi)[0], # type: ignore [arg-type]
|
|
27
|
+
web3.codec,
|
|
28
|
+
{"node": web3.ens.namehash("v2.registry.ychad.eth")}, # type: ignore [union-attr]
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__all__ = ["resolver", "topics"]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# mypy: disable-error-code="list-item"
|
|
2
|
+
"""
|
|
3
|
+
Error log suppression utilities for the Yearn Treasury exporter.
|
|
4
|
+
|
|
5
|
+
This module suppresses noisy or irrelevant eth-portfolio error logs for specific
|
|
6
|
+
token addresses that are known to be deprecated or otherwise unpricable.
|
|
7
|
+
|
|
8
|
+
To suppress logs for additional tokens, add their addresses to the
|
|
9
|
+
`suppress_logs_for[Network.<chain>]` mapping. The rest will be done
|
|
10
|
+
automatically on package import.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from typing import Dict, Final, List
|
|
14
|
+
|
|
15
|
+
from cchecksum import to_checksum_address
|
|
16
|
+
from eth_portfolio._utils import SUPPRESS_ERROR_LOGS
|
|
17
|
+
from eth_typing import HexAddress
|
|
18
|
+
from y import Network
|
|
19
|
+
|
|
20
|
+
from yearn_treasury.constants import CHAINID
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
suppress_logs_for: Final[Dict[Network, List[HexAddress]]] = {
|
|
24
|
+
Network.Mainnet: [
|
|
25
|
+
"0xBF7AA989192b020a8d3e1C65a558e123834325cA", # unpriceable yvWBTC - This vault had a bug and does not have a pricePerShare
|
|
26
|
+
"0x5aFE3855358E112B5647B952709E6165e1c1eEEe", # SAFE - This was not tradeable at the time of the first airdrops
|
|
27
|
+
"0x718AbE90777F5B778B52D553a5aBaa148DD0dc5D", # yvCurve-alETH - The underlying curve pool had an issue and is unpriceable
|
|
28
|
+
"0x3819f64f282bf135d62168C1e513280dAF905e06", # HDRN
|
|
29
|
+
"0x5fAa989Af96Af85384b8a938c2EdE4A7378D9875", # GAL
|
|
30
|
+
],
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def setup_eth_portfolio_logging() -> None:
|
|
35
|
+
"""
|
|
36
|
+
Suppress eth-portfolio error logs for specific tokens on the current chain.
|
|
37
|
+
|
|
38
|
+
Appends token addresses from the suppress_logs_for mapping (for the current
|
|
39
|
+
CHAINID) to the SUPPRESS_ERROR_LOGS list, preventing error logs for these
|
|
40
|
+
tokens from being emitted during analytics and reporting.
|
|
41
|
+
"""
|
|
42
|
+
for token in suppress_logs_for.get(CHAINID, []): # type: ignore [call-overload]
|
|
43
|
+
SUPPRESS_ERROR_LOGS.append(to_checksum_address(token))
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
1:
|
|
2
|
+
Yearn Treasury V1:
|
|
3
|
+
- "0xb99a40fcE04cb740EB79fC04976CA15aF69AaaaE"
|
|
4
|
+
Yearn Strategist Multisig: # refactor this to do from python from constants file
|
|
5
|
+
- "0x16388463d60FFE0661Cf7F1f31a7D658aC790ff7"
|
|
6
|
+
yMechs Multisig:
|
|
7
|
+
- "0x2C01B4AD51a67E2d8F02208F54dF9aC4c0B778B6"
|
|
8
|
+
ySwap Multisig:
|
|
9
|
+
- "0x7d2aB9CA511EBD6F03971Fb417d3492aA82513f0"
|
|
10
|
+
Yearn KP3R Wallet:
|
|
11
|
+
- "0x8d12a197cb00d4747a1fe03395095ce2a5cc6819"
|
|
12
|
+
Token Dumper Multisig:
|
|
13
|
+
- "0xC001d00d425Fa92C4F840baA8f1e0c27c4297a0B"
|
|
14
|
+
Cowswap Multisig:
|
|
15
|
+
- "0xA03be496e67Ec29bC62F01a428683D7F9c204930"
|
|
16
|
+
dYFI Redemption Contract:
|
|
17
|
+
- "0x7dC3A74F0684fc026f9163C6D5c3C99fda2cf60a"
|
|
18
|
+
Yearn veFarming Multisig:
|
|
19
|
+
- "0x4fc1b14cD213e7B6212145Ba4f180C3d53d1A11e"
|
|
20
|
+
CRV Buyer Contract (DAI):
|
|
21
|
+
- "0x0000000000007F150Bd6f54c40A34d7C3d5e9f56"
|
|
22
|
+
CRV Buyer Contract (USDT):
|
|
23
|
+
- "0x0000000000005117Dd3A72E64a705198753FDD54"
|
|
24
|
+
YFI Buyer Contract:
|
|
25
|
+
- "0x0000000000884A0E1fB44F9E24Fa3BDB19514fAE"
|
|
26
|
+
- "0x0000000000051666BBfBB42925C3eE5d50cF6B10"
|
|
27
|
+
Multichain Fantom Bridge:
|
|
28
|
+
- "0xC564EE9f21Ed8A2d8E7e76c085740d5e4c5FaFbE"
|
|
29
|
+
yLockers Multisig:
|
|
30
|
+
- "0x4444AAAACDBa5580282365e25b16309Bd770ce4a"
|
|
31
|
+
yRoboTreasury Treasury Contract:
|
|
32
|
+
- "0xEf77cc176c748d291EfB6CdC982c5744fC7211c8"
|
|
33
|
+
yRoboTreasury Stables Reserve:
|
|
34
|
+
- "0x278374fFb10B7D16E7633444c13e6E565EA57c28"
|
|
35
|
+
yearn.fi Dutch Auctions:
|
|
36
|
+
- "0x861fE45742f70054917B65bE18904662bD0dBd30"
|
|
37
|
+
250:
|
|
38
|
+
Yearn Strategist Multisig:
|
|
39
|
+
- "0x72a34AbafAB09b15E7191822A679f28E067C4a16"
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Budget request data model for Yearn Treasury.
|
|
3
|
+
|
|
4
|
+
This module defines the BudgetRequest dataclass, which models a single
|
|
5
|
+
budget request and its state. It provides methods for checking approval,
|
|
6
|
+
rejection, streaming, vesting, and payment status.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
from logging import getLogger
|
|
11
|
+
from typing import Final, Optional, Set, final
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
logger: Final = getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@final
|
|
18
|
+
@dataclass(frozen=True)
|
|
19
|
+
class BudgetRequest:
|
|
20
|
+
id: int
|
|
21
|
+
number: int
|
|
22
|
+
title: str
|
|
23
|
+
state: str
|
|
24
|
+
url: str
|
|
25
|
+
created_at: str
|
|
26
|
+
updated_at: str
|
|
27
|
+
closed_at: Optional[str]
|
|
28
|
+
body: Optional[str]
|
|
29
|
+
labels: Set[str]
|
|
30
|
+
|
|
31
|
+
def is_approved(self) -> bool:
|
|
32
|
+
return "approved" in self.labels
|
|
33
|
+
|
|
34
|
+
def is_rejected(self) -> bool:
|
|
35
|
+
return "rejected" in self.labels
|
|
36
|
+
|
|
37
|
+
def is_stream(self) -> bool:
|
|
38
|
+
return "stream" in self.labels
|
|
39
|
+
|
|
40
|
+
def is_vesting(self) -> bool:
|
|
41
|
+
return "vesting" in self.labels
|
|
42
|
+
|
|
43
|
+
def is_paid(self) -> bool:
|
|
44
|
+
return "paid" in self.labels
|