yearn-treasury 0.0.20__cp311-cp311-macosx_11_0_arm64.whl → 0.0.49__cp311-cp311-macosx_11_0_arm64.whl
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/__init__.py +2 -0
- yearn_treasury/_db.cpython-311-darwin.so +0 -0
- yearn_treasury/_db.py +21 -0
- yearn_treasury/_ens.cpython-311-darwin.so +0 -0
- yearn_treasury/_ens.py +14 -0
- yearn_treasury/_logging.cpython-311-darwin.so +0 -0
- yearn_treasury/_logging.py +43 -0
- yearn_treasury/address_labels.yaml +10 -0
- yearn_treasury/budget/__init__.cpython-311-darwin.so +0 -0
- yearn_treasury/budget/__init__.py +2 -2
- yearn_treasury/budget/_request.cpython-311-darwin.so +0 -0
- yearn_treasury/budget/_request.py +8 -0
- yearn_treasury/budget/_requests.cpython-311-darwin.so +0 -0
- yearn_treasury/budget/_requests.py +44 -17
- yearn_treasury/constants.py +20 -1
- yearn_treasury/main.py +54 -20
- yearn_treasury/rules/__init__.py +14 -0
- yearn_treasury/rules/constants.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/cost_of_revenue/gas.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/cost_of_revenue/gas.py +9 -1
- yearn_treasury/rules/expense/__init__.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/expense/general.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/expense/infrastructure.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/expense/infrastructure.py +7 -0
- yearn_treasury/rules/expense/people.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/expense/people.py +43 -0
- yearn_treasury/rules/expense/security.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/expense/security.py +17 -0
- yearn_treasury/rules/ignore/general.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/maker.py +36 -24
- yearn_treasury/rules/ignore/passthru.py +154 -11
- yearn_treasury/rules/ignore/swaps/__init__.py +4 -0
- yearn_treasury/rules/ignore/swaps/aave.py +26 -10
- yearn_treasury/rules/ignore/swaps/auctions.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/auctions.py +31 -0
- yearn_treasury/rules/ignore/swaps/compound.py +32 -22
- yearn_treasury/rules/ignore/swaps/conversion_factory.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/conversion_factory.py +21 -0
- yearn_treasury/rules/ignore/swaps/cowswap.py +16 -13
- yearn_treasury/rules/ignore/swaps/curve.py +54 -16
- yearn_treasury/rules/ignore/swaps/gearbox.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/gearbox.py +8 -0
- yearn_treasury/rules/ignore/swaps/iearn.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/iearn.py +4 -4
- yearn_treasury/rules/ignore/swaps/{curve.cpython-311-darwin.so → otc.cpython-311-darwin.so} +0 -0
- yearn_treasury/rules/ignore/swaps/otc.py +58 -0
- yearn_treasury/rules/ignore/swaps/pooltogether.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/pooltogether.py +7 -0
- yearn_treasury/rules/ignore/swaps/synthetix.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/uniswap.py +29 -6
- yearn_treasury/rules/ignore/swaps/unwrapper.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/unwrapper.py +8 -0
- yearn_treasury/rules/ignore/swaps/vaults.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/vaults.py +13 -11
- yearn_treasury/rules/ignore/swaps/woofy.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/woofy.py +80 -0
- yearn_treasury/rules/ignore/swaps/yfi.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/swaps/yfi.py +59 -7
- yearn_treasury/rules/ignore/swaps/yla.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/unit.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/unit.py +6 -1
- yearn_treasury/rules/ignore/weth.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/ignore/weth.py +8 -0
- yearn_treasury/rules/ignore/ygov.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_expense/__init__.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_expense/boost.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_expense/bugs.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_expense/donations.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_expense/donations.py +8 -0
- yearn_treasury/rules/other_expense/dyfi.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_expense/events.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_expense/misc.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_expense/misc.py +8 -0
- yearn_treasury/rules/other_expense/revshare.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_income/__init__.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_income/__init__.py +2 -100
- yearn_treasury/rules/other_income/airdrops.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_income/airdrops.py +30 -0
- yearn_treasury/rules/other_income/misc.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/other_income/misc.py +80 -0
- yearn_treasury/rules/revenue/bribes.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/revenue/farming.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/revenue/keepcoins.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/revenue/seasolver.cpython-311-darwin.so +0 -0
- yearn_treasury/rules/revenue/vaults.py +14 -10
- yearn_treasury/rules/revenue/yteams.cpython-311-darwin.so +0 -0
- yearn_treasury/shitcoins.py +61 -2
- yearn_treasury/vaults.cpython-311-darwin.so +0 -0
- yearn_treasury/vaults.py +17 -4
- yearn_treasury/yteams.py +208 -0
- {yearn_treasury-0.0.20.dist-info → yearn_treasury-0.0.49.dist-info}/METADATA +3 -3
- yearn_treasury-0.0.49.dist-info/RECORD +128 -0
- yearn_treasury-0.0.49.dist-info/top_level.txt +2 -0
- yearn_treasury__mypyc.cpython-311-darwin.so +0 -0
- de0b3d5d46e8d426aa59__mypyc.cpython-311-darwin.so +0 -0
- yearn_treasury-0.0.20.dist-info/RECORD +0 -113
- yearn_treasury-0.0.20.dist-info/top_level.txt +0 -2
- {yearn_treasury-0.0.20.dist-info → yearn_treasury-0.0.49.dist-info}/WHEEL +0 -0
- {yearn_treasury-0.0.20.dist-info → yearn_treasury-0.0.49.dist-info}/entry_points.txt +0 -0
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Other expense rules for miscellaneous cases in Yearn Treasury.
|
|
3
|
+
|
|
4
|
+
This module defines matching logic for miscellaneous other expenses.
|
|
5
|
+
If it doesn't really fit anywhere else in :mod:`~other_expenses`,
|
|
6
|
+
it will end up in here.
|
|
7
|
+
"""
|
|
8
|
+
|
|
1
9
|
from dao_treasury import TreasuryTx, other_expense
|
|
2
10
|
from y import Network
|
|
3
11
|
|
|
Binary file
|
|
Binary file
|
|
@@ -1,100 +1,2 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
3
|
-
|
|
4
|
-
from dao_treasury import TreasuryTx, other_income
|
|
5
|
-
from y import Contract, ContractNotVerified, ERC20, Network # type: ignore [attr-defined]
|
|
6
|
-
|
|
7
|
-
from yearn_treasury.rules.constants import ZERO_ADDRESS
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
_POINT_ONE: Final = Decimal("0.1")
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@other_income("Airdrop", Network.Mainnet)
|
|
14
|
-
def is_airdrop(tx: TreasuryTx) -> bool:
|
|
15
|
-
txhash = tx.hash
|
|
16
|
-
return txhash in {
|
|
17
|
-
"0x327684dab9e3ce61d125b36fe0b59cbfbc8aa5ac7a5b051125ab7cac3b93b90b",
|
|
18
|
-
"0x3424e8a6688c89f7974968213c8c25f3bd8100f78c54475edb001c11a8ad5d21", # Gnosis SAFE airdrop
|
|
19
|
-
"0xb39f2991fdc2c70b43046be3eac36bff35c21c7f66e2888a52afc3956abae451", # Gnosis SAFE airdrop
|
|
20
|
-
"0x4923fd32b4eacdc1617700c67176935676ca4d06bbfbb73644730c55534623db", # Gnosis SAFE airdrop
|
|
21
|
-
"0x5ba604cae0d355835b182fa23c8a58ae695905e69ed08c7cf8a52f3eca889484", # Gnosis SAFE airdrop
|
|
22
|
-
"0x44f7d3b2030799ea45932baf6049528a059aabd6387f3128993d646d01c8e877", # TKX
|
|
23
|
-
"0xf2dbe58dffd3bc1476755e9f74e2ae07531579d0a3ea9e2aaac2ef902e080c2a", # TKX
|
|
24
|
-
"0x8079e9cae847da196dc5507561bc9d1434f765f05045bc1a82df735ec83bc6ec", # MTV
|
|
25
|
-
"0x037a9cc5baa7d63a11d0f0720ee552bbf4ad85118ee5425220a263695fedbe9f", # Gnosis SAFE airdrop
|
|
26
|
-
# NOTE: this one was rec'd elsewhere, dumped, and WETH sent to treasury
|
|
27
|
-
"0xc12ded505ea158717890e4ae6e7ab5eb5cb61edbc13dfd125dd0e6f9b1af9477", # Gnosis SAFE airdrop
|
|
28
|
-
"0x7c086a82b43b2f49db93b76a0698cf86a9c620b3bf924f0003175b04a17455ad", # PRISMA
|
|
29
|
-
} or (
|
|
30
|
-
# Gnosis SAFE airdrop
|
|
31
|
-
txhash == "0xe8b5a4ebf1f04048f6226b22b2865a33621e88ea255dcea0cfd7a975a3a7e387"
|
|
32
|
-
and tx.log_index == 72
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
@other_income("aToken Yield", Network.Mainnet)
|
|
37
|
-
def is_atoken_yield(tx: TreasuryTx) -> bool:
|
|
38
|
-
return (
|
|
39
|
-
tx.symbol in ("aLEND", "aLINK")
|
|
40
|
-
and tx.from_address.address == ZERO_ADDRESS
|
|
41
|
-
and tx.to_nickname in ("Yearn Treasury", "Yearn Treasury V1")
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@other_income("RoboVault Thank You", Network.Fantom)
|
|
46
|
-
async def is_robovault_share(tx: TreasuryTx) -> bool:
|
|
47
|
-
"""
|
|
48
|
-
After Yearn devs helped robovault with a vulnerability, robovault committed to sending Yearn a portion of their fees.
|
|
49
|
-
"""
|
|
50
|
-
if not tx.symbol.startswith("rv") and tx.from_address.is_contract:
|
|
51
|
-
return False
|
|
52
|
-
|
|
53
|
-
try:
|
|
54
|
-
strat = await Contract.coroutine(tx.from_address.address)
|
|
55
|
-
except ContractNotVerified:
|
|
56
|
-
return False
|
|
57
|
-
|
|
58
|
-
if not hasattr(strat, "vault"):
|
|
59
|
-
return False
|
|
60
|
-
|
|
61
|
-
if await strat.vault.coroutine(block_identifier=tx.block) == tx.token:
|
|
62
|
-
return True
|
|
63
|
-
|
|
64
|
-
return (
|
|
65
|
-
tx.from_nickname == "Contract: Strategy"
|
|
66
|
-
and tx.symbol == "rv3USDCc"
|
|
67
|
-
and await ERC20( # type: ignore [call-overload]
|
|
68
|
-
await strat.vault.coroutine(block_identifier=tx.block),
|
|
69
|
-
asynchronous=True,
|
|
70
|
-
).symbol
|
|
71
|
-
== "rv3USDCb"
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
@other_income("Cowswap Gas Reimbursement", Network.Mainnet)
|
|
76
|
-
def is_cowswap_gas_reimbursement(tx: TreasuryTx) -> bool:
|
|
77
|
-
return (
|
|
78
|
-
tx.symbol == "ETH"
|
|
79
|
-
and tx.from_nickname == "Cowswap Multisig"
|
|
80
|
-
and tx.to_nickname == "yMechs Multisig"
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
@other_income("USDS Referral Code", Network.Mainnet)
|
|
85
|
-
def is_usds_referral_code(tx: TreasuryTx) -> bool:
|
|
86
|
-
"""Yearn earns some USDS for referring deposits to Maker"""
|
|
87
|
-
return (
|
|
88
|
-
tx.symbol == "USDS"
|
|
89
|
-
and tx.from_address.address == "0x3C5142F28567E6a0F172fd0BaaF1f2847f49D02F"
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
@other_income("yETH Application Fee", Network.Mainnet)
|
|
94
|
-
def is_yeth_application_fee(tx: TreasuryTx) -> bool:
|
|
95
|
-
return tx.symbol == "yETH" and tx.to_nickname == "Yearn Treasury" and tx.amount == _POINT_ONE
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
@other_income("yPRISMA Fees", Network.Mainnet)
|
|
99
|
-
def is_yprisma_fees(tx: TreasuryTx) -> bool:
|
|
100
|
-
return tx.symbol == "yvmkUSD-A" and tx.from_nickname == "Contract: YPrismaFeeDistributor"
|
|
1
|
+
from yearn_treasury.rules.other_income.airdrops import *
|
|
2
|
+
from yearn_treasury.rules.other_income.misc import *
|
|
Binary file
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
from typing import Final
|
|
2
|
+
|
|
3
|
+
from dao_treasury import TreasuryTx, other_income
|
|
4
|
+
from y import Network
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
airdrop: Final = other_income("Airdrop")
|
|
8
|
+
|
|
9
|
+
_SAFE_AIRDROP_CONTRACTS: Final = (
|
|
10
|
+
"0xA0b937D5c8E32a80E3a8ed4227CD020221544ee6",
|
|
11
|
+
"0xC0fde70A65C7569Fe919bE57492228DEE8cDb585",
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@airdrop("SAFE", Network.Mainnet)
|
|
16
|
+
def is_safe_airdrop(tx: TreasuryTx) -> bool:
|
|
17
|
+
return tx.symbol == "SAFE" and tx.from_address.address in _SAFE_AIRDROP_CONTRACTS # type: ignore [union-attr]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@airdrop("Other", Network.Mainnet)
|
|
21
|
+
def is_airdrop(tx: TreasuryTx) -> bool:
|
|
22
|
+
return tx.hash in {
|
|
23
|
+
"0x327684dab9e3ce61d125b36fe0b59cbfbc8aa5ac7a5b051125ab7cac3b93b90b",
|
|
24
|
+
"0x44f7d3b2030799ea45932baf6049528a059aabd6387f3128993d646d01c8e877", # TKX
|
|
25
|
+
"0xf2dbe58dffd3bc1476755e9f74e2ae07531579d0a3ea9e2aaac2ef902e080c2a", # TKX
|
|
26
|
+
"0x8079e9cae847da196dc5507561bc9d1434f765f05045bc1a82df735ec83bc6ec", # MTV
|
|
27
|
+
# NOTE: this one was rec'd elsewhere, dumped, and WETH sent to treasury
|
|
28
|
+
"0xc12ded505ea158717890e4ae6e7ab5eb5cb61edbc13dfd125dd0e6f9b1af9477", # Gnosis SAFE airdrop
|
|
29
|
+
"0x7c086a82b43b2f49db93b76a0698cf86a9c620b3bf924f0003175b04a17455ad", # PRISMA
|
|
30
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# mypy: disable-error-code="union-attr"
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
from typing import Final, Optional
|
|
4
|
+
|
|
5
|
+
from dao_treasury import TreasuryTx, other_income
|
|
6
|
+
from y import Contract, ContractNotVerified, ERC20, Network # type: ignore [attr-defined]
|
|
7
|
+
|
|
8
|
+
from yearn_treasury.rules.constants import ZERO_ADDRESS
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
_POINT_ONE: Final = Decimal("0.1")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@other_income("aToken Yield", Network.Mainnet)
|
|
15
|
+
def is_atoken_yield(tx: TreasuryTx) -> bool:
|
|
16
|
+
return (
|
|
17
|
+
tx.symbol in ("aLEND", "aLINK")
|
|
18
|
+
and tx.from_address.address == ZERO_ADDRESS
|
|
19
|
+
and tx.to_nickname in ("Yearn Treasury", "Yearn Treasury V1")
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@other_income("RoboVault Thank You", Network.Fantom)
|
|
24
|
+
async def is_robovault_share(tx: TreasuryTx) -> bool:
|
|
25
|
+
"""
|
|
26
|
+
After Yearn devs helped robovault with a vulnerability, robovault committed to sending Yearn a portion of their fees.
|
|
27
|
+
"""
|
|
28
|
+
if not tx.symbol.startswith("rv") and tx.from_address.is_contract:
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
try:
|
|
32
|
+
strat = await tx.from_address.contract_coro
|
|
33
|
+
except ContractNotVerified:
|
|
34
|
+
return False
|
|
35
|
+
else:
|
|
36
|
+
vault: Optional[Contract] = getattr(strat, "vault", None)
|
|
37
|
+
|
|
38
|
+
if vault is None:
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
if await vault.coroutine(block_identifier=tx.block) == tx.token:
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
tx.from_nickname == "Contract: Strategy"
|
|
46
|
+
and tx.symbol == "rv3USDCc"
|
|
47
|
+
and await ERC20( # type: ignore [call-overload]
|
|
48
|
+
await vault.coroutine(block_identifier=tx.block),
|
|
49
|
+
asynchronous=True,
|
|
50
|
+
).symbol
|
|
51
|
+
== "rv3USDCb"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@other_income("Cowswap Gas Reimbursement", Network.Mainnet)
|
|
56
|
+
def is_cowswap_gas_reimbursement(tx: TreasuryTx) -> bool:
|
|
57
|
+
return (
|
|
58
|
+
tx.symbol == "ETH"
|
|
59
|
+
and tx.from_nickname == "Cowswap Multisig"
|
|
60
|
+
and tx.to_nickname == "yMechs Multisig"
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@other_income("USDS Referral Code", Network.Mainnet)
|
|
65
|
+
def is_usds_referral_code(tx: TreasuryTx) -> bool:
|
|
66
|
+
"""Yearn earns some USDS for referring deposits to Maker"""
|
|
67
|
+
return (
|
|
68
|
+
tx.symbol == "USDS"
|
|
69
|
+
and tx.from_address.address == "0x3C5142F28567E6a0F172fd0BaaF1f2847f49D02F"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@other_income("yETH Application Fee", Network.Mainnet)
|
|
74
|
+
def is_yeth_application_fee(tx: TreasuryTx) -> bool:
|
|
75
|
+
return tx.symbol == "yETH" and tx.to_nickname == "Yearn Treasury" and tx.amount == _POINT_ONE
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@other_income("yPRISMA Fees", Network.Mainnet)
|
|
79
|
+
def is_yprisma_fees(tx: TreasuryTx) -> bool:
|
|
80
|
+
return tx.symbol == "yvmkUSD-A" and tx.from_nickname == "Contract: YPrismaFeeDistributor"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
1
2
|
from logging import getLogger
|
|
2
|
-
from typing import Final, Optional
|
|
3
|
+
from typing import Final, Optional, cast
|
|
3
4
|
|
|
4
|
-
from async_lru import alru_cache
|
|
5
5
|
from dao_treasury import TreasuryTx, revenue
|
|
6
6
|
from eth_typing import ChecksumAddress
|
|
7
|
+
from faster_async_lru import alru_cache
|
|
7
8
|
from y import Contract, Network
|
|
8
9
|
|
|
9
10
|
from yearn_treasury.vaults import v1, v2
|
|
@@ -55,7 +56,7 @@ async def _get_controller(vault: Contract) -> Contract:
|
|
|
55
56
|
|
|
56
57
|
@fees("Vaults V1", Network.Mainnet)
|
|
57
58
|
async def is_v1_vault_fees(tx: TreasuryTx) -> bool:
|
|
58
|
-
token = tx.
|
|
59
|
+
token = tx.token_address
|
|
59
60
|
|
|
60
61
|
# Fees from single-sided strategies are not denominated in `vault.token` but everything else is
|
|
61
62
|
is_single_sided = _is_single_sided(tx)
|
|
@@ -85,7 +86,9 @@ async def is_v1_vault_fees(tx: TreasuryTx) -> bool:
|
|
|
85
86
|
return False
|
|
86
87
|
|
|
87
88
|
|
|
88
|
-
def is_inverse_fees_from_stash_contract(
|
|
89
|
+
def is_inverse_fees_from_stash_contract(
|
|
90
|
+
from_address: ChecksumAddress, to_nickname: str | None
|
|
91
|
+
) -> bool:
|
|
89
92
|
return (
|
|
90
93
|
from_address == "0xE376e8e8E3B0793CD61C6F1283bA18548b726C2e"
|
|
91
94
|
and to_nickname == "Token: Curve stETH Pool yVault"
|
|
@@ -94,18 +97,19 @@ def is_inverse_fees_from_stash_contract(from_address: str, to_nickname: str) ->
|
|
|
94
97
|
|
|
95
98
|
@fees("Vaults V2")
|
|
96
99
|
async def is_v2_vault_fees(tx: TreasuryTx) -> bool:
|
|
97
|
-
token = tx.
|
|
98
|
-
from_address = tx.from_address.address
|
|
100
|
+
token = tx.token_address
|
|
101
|
+
from_address = cast(ChecksumAddress, tx.from_address.address)
|
|
99
102
|
if (
|
|
100
103
|
from_address == token
|
|
101
|
-
and (vault := v2.get(from_address))
|
|
104
|
+
and (vault := v2.get(from_address))
|
|
102
105
|
and tx.to_address == await vault.rewards.coroutine(block_identifier=tx.block)
|
|
103
106
|
):
|
|
104
107
|
return True
|
|
105
108
|
|
|
106
|
-
if is_inverse_fees_from_stash_contract(from_address, tx.to_nickname):
|
|
107
|
-
|
|
108
|
-
|
|
109
|
+
if is_inverse_fees_from_stash_contract(from_address, tx.to_nickname):
|
|
110
|
+
value_usd = cast(Decimal, tx.value_usd)
|
|
111
|
+
if value_usd > 0:
|
|
112
|
+
tx.value_usd = -value_usd
|
|
109
113
|
return True
|
|
110
114
|
|
|
111
115
|
return False
|
|
Binary file
|
yearn_treasury/shitcoins.py
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
List of "shitcoins" (but like, actual shit shitcoins) to ignore in all
|
|
3
|
+
Yearn Treasury analytics.
|
|
4
|
+
|
|
5
|
+
This module defines, for each blockchain network, a set of token addresses
|
|
6
|
+
known to be unpricable, considered as spam, or otherwise unwanted for
|
|
7
|
+
reporting and analytics. These tokens are passed in to :mod:`eth-portfolio`,
|
|
8
|
+
which contains the logic that prevents these shitcoins from being included in
|
|
9
|
+
any Yearn Treasury outputs.
|
|
10
|
+
|
|
11
|
+
Since these tokens do nothing but add noise to the outputs, transactions
|
|
12
|
+
involving them are excluded from treasury calculations, reports, and dashboards.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import Final
|
|
16
|
+
|
|
1
17
|
from y import Network, convert
|
|
2
18
|
from y.constants import CHAINID
|
|
3
19
|
|
|
4
20
|
|
|
5
|
-
_SHITCOINS = {
|
|
21
|
+
_SHITCOINS: Final = {
|
|
6
22
|
Network.Mainnet: (
|
|
7
23
|
"0xC36442b4a4522E871399CD717aBDD847Ab11FE88", # UNI-V3 NFT, not shitcoin but not pricable
|
|
8
24
|
"0x0329b631464C43f4e8132df7B4ac29a2D89FFdC7",
|
|
@@ -34,6 +50,13 @@ _SHITCOINS = {
|
|
|
34
50
|
"0xe5868468Cb6Dd5d6D7056bd93f084816c6eF075f",
|
|
35
51
|
"0x0a24Bb4842c301276c65086B5d78D5C872993c72",
|
|
36
52
|
"0x63125c0d5Cd9071de9A1ac84c400982f41C697AE",
|
|
53
|
+
"0x4d22921215cF37e8d49e2Ac6d1F5e9672f63A7c6",
|
|
54
|
+
"0xe2549E429B78458fa60BC7B1b284d4411E1D5105",
|
|
55
|
+
"0xCfdD747d041397bcE08B0Fe6ebF7Ef65E9F46795",
|
|
56
|
+
"0x9745969171a38B40db05c506fe2DA2C36f317627",
|
|
57
|
+
"0x6051C1354Ccc51b4d561e43b02735DEaE64768B8",
|
|
58
|
+
"0xf0814d0E47F2390a8082C4a1BD819FDDe50f9bFc",
|
|
59
|
+
"0x2DBd330bC9B7f3A822a9173aB52172BdDDcAcE2A",
|
|
37
60
|
# just andre tinkering
|
|
38
61
|
"0x5cB5e2d7Ab9Fd32021dF8F1D3E5269bD437Ec3Bf",
|
|
39
62
|
# these arent shitcoins per se but we can't price them and dont expect to in the future, lets save cpu cycles
|
|
@@ -50,6 +73,18 @@ _SHITCOINS = {
|
|
|
50
73
|
"0x57f19E7e1A9066a741f59484481C4D2E9150e9E2", # MOCO
|
|
51
74
|
"0xb092D8E13Ba50963D57bEcB17a037728D883D02d", # BABYLABUBU
|
|
52
75
|
"0x4E51960bd33A6edA71a8B24A76311834BD98DD9f", # AICC
|
|
76
|
+
"0xB85485421d8a41C4648AB80bE1A725fA6b5Bc86d", # MEGA
|
|
77
|
+
"0x46D0Fb47b1e91130D53498EbeE7A968e7e6599f9", # Ghibli
|
|
78
|
+
"0x4FbB350052Bca5417566f188eB2EBCE5b19BC964", # GRG
|
|
79
|
+
"0x1f6DEb07E1a19bAfF90EC4075447eeF6eb96c0BA", # BABYMANYU
|
|
80
|
+
"0xD10EFABA11A51237fa120b15153DD432958bbDE3", # JIFFPOM
|
|
81
|
+
"0xCd9594cd25ED2a166362b6F76c523da08c4Ef2e5", # ESTHER
|
|
82
|
+
"0x16B907b5d1208Ae6086dE983a5EF45E7890eF272", # JUNFOX
|
|
83
|
+
"0xdE56173463d6461001B0891bC90DB224965f5762", # MAGNUS
|
|
84
|
+
"0x922824A5b3B3D5f4485fF52F4Ab7Cba5eA491874", # POSEIDON
|
|
85
|
+
"0x84F7D2f6FB447Bb11d3E7Ce64D83e1c02c2F3078", # VIRTUAL
|
|
86
|
+
"0x5C6Ed14E1017cf75C237A4A4b93Ce1D2f83EB002", # GRVT
|
|
87
|
+
"0xf76E6eFf109258fd5F52823d9F9feE7c90C97251", # wkeyDAO
|
|
53
88
|
# test token?
|
|
54
89
|
"0x372d5d02c6b4075bd58892f80300cA590e92d29E", # tOUSG
|
|
55
90
|
# dETH? don't think this is needed
|
|
@@ -69,6 +104,16 @@ _SHITCOINS = {
|
|
|
69
104
|
"0xD2F89F59fBC7125b406e3F60A992DFa9FdB76524", # MISTRAL AI
|
|
70
105
|
"0xa0CCdBCeB5Da30F9d62F7A727F2B35C69dF08760", # CHUNK AI
|
|
71
106
|
"0x7CE31075d7450Aff4A9a82DdDF69D451B1e0C4E9", # DEEPSEEK AI
|
|
107
|
+
"0xf0f9C021AF9B6431FA59DAB75C8e6cB80c0dEa37", # TESLA AI
|
|
108
|
+
"0x635eeC65a7Ef10dCF96Bfe051D8A6e5960efe180", # KLING AI
|
|
109
|
+
"0xa3Efa0929569c15c20f89B591931899Fb05B4663", # GPT-5
|
|
110
|
+
"0x0A953979fdCfD82B08C77dB29705327BeC39ff13", # GROK4 AI
|
|
111
|
+
"0xc83377b9eE3CEe4Cc03CCd58AfdE1FB12864aEE3", # E AI
|
|
112
|
+
"0x927402ab67c0CDA3c187E9DFE34554AC581441f2", # SAITABIT
|
|
113
|
+
"0x691539810DF6e879A377C24CfEE130BBE92708d8", # NVIDIA AI
|
|
114
|
+
"0xdC82aC0A89197854cb2240FaBF7E7760a4fF4d9e", # NVIDIA
|
|
115
|
+
"0x5Fba8ea5A559CF5c99BA6dd884Ae17C1d621fE5B", # OSCAR AI
|
|
116
|
+
"0x57b055656460055192c8EAf616F90Ab76a32CC20", # Openx
|
|
72
117
|
# matt furry spam
|
|
73
118
|
"0x73228b3D33cC71cB721Fc62950577bE63bd9c8C9", # Maskman by Matt Furie
|
|
74
119
|
"0x7c28e66436C93BB9F657dDF2BA0eeeCf61369b92", # Bloodboy by Matt Furie
|
|
@@ -78,6 +123,20 @@ _SHITCOINS = {
|
|
|
78
123
|
"0x2F375Ce83EE85e505150d24E85A1742fd03cA593", # TEST
|
|
79
124
|
),
|
|
80
125
|
}
|
|
126
|
+
"""
|
|
127
|
+
Mapping of blockchain networks to tuples of token addresses that should be
|
|
128
|
+
ignored in Yearn Treasury analytics. These tokens are considered unpricable,
|
|
129
|
+
spam, or otherwise unwanted for reporting and analytics purposes.
|
|
130
|
+
|
|
131
|
+
Each tuple contains token contract addresses that will be excluded from
|
|
132
|
+
treasury calculations, reports, and dashboards for the corresponding network.
|
|
133
|
+
"""
|
|
134
|
+
|
|
81
135
|
|
|
136
|
+
SHITCOINS: Final = {convert.to_address(shitcoin) for shitcoin in _SHITCOINS.get(CHAINID, ())} # type: ignore [call-overload]
|
|
137
|
+
"""Set of checksummed token addresses to ignore for the current chain.
|
|
82
138
|
|
|
83
|
-
|
|
139
|
+
This set is derived from the _SHITCOINS mapping for the current CHAINID,
|
|
140
|
+
and is used to filter out unpricable, spam, or otherwise unwanted tokens
|
|
141
|
+
from all Yearn Treasury analytics and reporting.
|
|
142
|
+
"""
|
|
Binary file
|
yearn_treasury/vaults.py
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
"""
|
|
2
|
+
Vault discovery and tracking utilities for Yearn Treasury.
|
|
3
|
+
|
|
4
|
+
This module discovers Yearn vault contracts and maps them to their
|
|
5
|
+
underlying assets using Yearn's on-chain registry contracts. It
|
|
6
|
+
provides dictionaries for v1 and v2 vaults, supporting transaction
|
|
7
|
+
classification, analytics, and reporting across the Yearn Treasury
|
|
8
|
+
system.
|
|
9
|
+
|
|
10
|
+
Key Responsibilities:
|
|
11
|
+
- Discover and map all v1 and v2 vault contracts to underlying assets at startup.
|
|
12
|
+
- Provide lookup tables for use in vault deposit/withdrawal sort rules.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from typing import Dict, Final
|
|
2
16
|
|
|
3
17
|
from brownie import chain
|
|
4
18
|
from eth_typing import ChecksumAddress
|
|
@@ -27,11 +41,10 @@ if chain.id == Network.Mainnet:
|
|
|
27
41
|
|
|
28
42
|
# TODO: make resolve_ens util in eth-port and refactor this out
|
|
29
43
|
v2_registries = [
|
|
30
|
-
event["newAddress"].hex()
|
|
31
|
-
for event in Events(addresses=resolver, topics=topics).events(now)
|
|
44
|
+
event["newAddress"].hex() for event in Events(addresses=resolver, topics=topics).events(now)
|
|
32
45
|
]
|
|
33
46
|
|
|
34
47
|
for event in Events(addresses=list(map(str, v2_registries))).events(now):
|
|
35
48
|
if event.name == "NewVault":
|
|
36
49
|
vault_address = event["vault"]
|
|
37
|
-
v2[vault_address] = Contract(vault_address)
|
|
50
|
+
v2[vault_address] = Contract(vault_address)
|
yearn_treasury/yteams.py
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# This is a loose copy of an old script and will not likely be refactored into something pretty
|
|
2
|
+
import os
|
|
3
|
+
from datetime import datetime, timedelta, timezone
|
|
4
|
+
from decimal import Decimal
|
|
5
|
+
from functools import lru_cache
|
|
6
|
+
from logging import getLogger
|
|
7
|
+
from typing import Any, Dict, Final, List, Set, Tuple
|
|
8
|
+
|
|
9
|
+
import a_sync
|
|
10
|
+
from brownie import chain
|
|
11
|
+
from eth_portfolio.structs import TokenTransfer
|
|
12
|
+
from eth_portfolio._ydb.token_transfers import InboundTokenTransfers
|
|
13
|
+
from pandas import DataFrame, MultiIndex
|
|
14
|
+
from y import Contract, Network, get_block_at_timestamp
|
|
15
|
+
from y.exceptions import ContractNotVerified
|
|
16
|
+
|
|
17
|
+
from yearn_treasury.constants import ZERO_ADDRESS
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
DATA_FOLDER: Final = os.path.join(".", "data")
|
|
21
|
+
OUTPUT_FILE: Final = os.path.join(DATA_FOLDER, f"teams_revenue_{chain.id}.csv")
|
|
22
|
+
NUMBER_OF_MONTHS_TO_INCLUDE_IN_REPORT: Final = 36
|
|
23
|
+
|
|
24
|
+
if not os.path.exists(DATA_FOLDER):
|
|
25
|
+
os.makedirs(DATA_FOLDER)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# TODO: maybe move this into constants for reuse
|
|
29
|
+
yteams_addresses = {
|
|
30
|
+
Network.Mainnet: {
|
|
31
|
+
"v3": {
|
|
32
|
+
"ms": "0x33333333D5eFb92f19a5F94a43456b3cec2797AE",
|
|
33
|
+
"splits": {"0x2A12CAA2c13Af03c117D836CA3811a5Ca946133B": 12.5},
|
|
34
|
+
},
|
|
35
|
+
"dinobots": {
|
|
36
|
+
"ms": "0x2C01B4AD51a67E2d8F02208F54dF9aC4c0B778B6",
|
|
37
|
+
"splits": {"0xC4f238633A85A854C4702d2c66264771D1fa7904": 17.5},
|
|
38
|
+
},
|
|
39
|
+
"ylockers": {
|
|
40
|
+
"ms": "0x4444AAAACDBa5580282365e25b16309Bd770ce4a",
|
|
41
|
+
"splits": {
|
|
42
|
+
"0xac580302548FCCBBf00020de20C3A8AA516821AD": 2.5,
|
|
43
|
+
"0x794f80E899c772de9E326eC83cCfD8D94e208B49": 6.25,
|
|
44
|
+
"0x5FF0f87b05806ce89967638CA727Af8309d92A89": 12.5,
|
|
45
|
+
"0x5A7575368797695BefD785f546C6b8B7e9D37f8c": 15.625,
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
# "ylockers others": {"ms": "0x4444AAAACDBa5580282365e25b16309Bd770ce4a","splits":{"0x5FF0f87b05806ce89967638CA727Af8309d92A89":12.5, "0x5A7575368797695BefD785f546C6b8B7e9D37f8c":15.625}},
|
|
49
|
+
"yaudit": {
|
|
50
|
+
"ms": "0x8973B848775a87a0D5bcf262C555859b87E6F7dA",
|
|
51
|
+
"splits": {
|
|
52
|
+
"0xd7A1DBe236A38528D54317415a530b2326068373": 35,
|
|
53
|
+
"0xF104F38592287e25868BD8C3dcCCa1a311916f88": 35,
|
|
54
|
+
"0x1a9D272C3b7fE427639702A332D51348213B0bC1": 20,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
"yeth": {
|
|
58
|
+
"ms": "0xeEEEEeeeEe274C3CCe13f77C85d8eBd9F7fd4479",
|
|
59
|
+
"splits": {"0x14EFe6390C6758E3fE4379A14e3B329274b1b072": 25},
|
|
60
|
+
},
|
|
61
|
+
"yfarm": {
|
|
62
|
+
"ms": "0x55157997cb324a374cCd7c40914ff879Fd9D515C",
|
|
63
|
+
"splits": {"0x0B3cCe59E038373F6008D9266B6D6eB4d21689b1": 50},
|
|
64
|
+
},
|
|
65
|
+
"sms": {
|
|
66
|
+
"ms": "0x16388463d60FFE0661Cf7F1f31a7D658aC790ff7",
|
|
67
|
+
"splits": {"0xd6748776CF06a80EbE36cd83D325B31bb916bf54": 25},
|
|
68
|
+
},
|
|
69
|
+
}
|
|
70
|
+
}[Network(chain.id)]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
logger: Final = getLogger(__name__)
|
|
74
|
+
|
|
75
|
+
_not_verified: Final[Set[str]] = set()
|
|
76
|
+
_warned: Final[Set[TokenTransfer]] = set()
|
|
77
|
+
|
|
78
|
+
_known_tokens_without_prices: Final = frozenset({"SAFE", "vCOW"})
|
|
79
|
+
"""When there is a PriceError for these tokens, no logs will be emitted."""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@lru_cache(maxsize=None)
|
|
83
|
+
def transfers_for(wallet: str) -> InboundTokenTransfers:
|
|
84
|
+
return InboundTokenTransfers(wallet, 0, load_prices=True) # type: ignore [arg-type]
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
async def calculate_teams_revenue_expenses() -> None:
|
|
88
|
+
logger.info("Starting process to calculate teams revenues and expenses")
|
|
89
|
+
timestamps = get_timestamps_for_report()
|
|
90
|
+
|
|
91
|
+
async def get_coros_for_timestamp(dt: datetime) -> Dict[str, Dict[str, Decimal]]:
|
|
92
|
+
return await a_sync.gather(
|
|
93
|
+
{
|
|
94
|
+
label: total(label, wallet_info, dt)
|
|
95
|
+
for label, wallet_info in yteams_addresses.items()
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
all_data = await a_sync.gather({dt: get_coros_for_timestamp(dt) for dt in timestamps})
|
|
100
|
+
|
|
101
|
+
result = {
|
|
102
|
+
(dt, teams, movement): values
|
|
103
|
+
for dt, data in all_data.items()
|
|
104
|
+
for teams, info in data.items()
|
|
105
|
+
for movement, values in info.items()
|
|
106
|
+
}
|
|
107
|
+
df = DataFrame.from_dict(result, orient="index")
|
|
108
|
+
print("------------")
|
|
109
|
+
# print(df.index)
|
|
110
|
+
# print(df.head(10))
|
|
111
|
+
df.index = MultiIndex.from_tuples(df.index)
|
|
112
|
+
print("********")
|
|
113
|
+
# print(df.index)
|
|
114
|
+
df.reset_index(inplace=True)
|
|
115
|
+
df.columns = ["datetime", "team", "label", "value"]
|
|
116
|
+
df.to_csv(OUTPUT_FILE)
|
|
117
|
+
logger.info(
|
|
118
|
+
f"Finished processing yteams calculations and saved file to {os.path.abspath(OUTPUT_FILE)}"
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def get_timestamps_for_report() -> List[datetime]:
|
|
123
|
+
now = datetime.now(tz=timezone.utc)
|
|
124
|
+
prev_month_end = datetime(
|
|
125
|
+
year=now.year,
|
|
126
|
+
month=now.month,
|
|
127
|
+
day=1,
|
|
128
|
+
hour=0,
|
|
129
|
+
minute=0,
|
|
130
|
+
second=0,
|
|
131
|
+
microsecond=0,
|
|
132
|
+
tzinfo=timezone.utc,
|
|
133
|
+
) - timedelta(microseconds=1)
|
|
134
|
+
datetimes = []
|
|
135
|
+
print("Exporting report for timestamps:")
|
|
136
|
+
for _ in range(NUMBER_OF_MONTHS_TO_INCLUDE_IN_REPORT):
|
|
137
|
+
print(f" - {prev_month_end}")
|
|
138
|
+
datetimes.append(prev_month_end)
|
|
139
|
+
prev_month_end -= timedelta(days=prev_month_end.day)
|
|
140
|
+
return datetimes
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
async def total(label: str, wallet_info: Dict[str, Any], timestamp: datetime) -> Dict[str, Decimal]:
|
|
144
|
+
rev = await sum_revenue_transfers.sum(wallet_info["splits"].items(), timestamp=timestamp)
|
|
145
|
+
grants = await sum_grants_received(wallet_info["ms"], timestamp)
|
|
146
|
+
if rev > 10_000_000:
|
|
147
|
+
raise ValueError(rev)
|
|
148
|
+
if grants > 10_000_000:
|
|
149
|
+
raise ValueError(grants)
|
|
150
|
+
net = rev - grants
|
|
151
|
+
if label == "yaudit":
|
|
152
|
+
logger.info("--- %s thru %s ---", label, timestamp)
|
|
153
|
+
logger.info("inbound %s", rev)
|
|
154
|
+
logger.info("grants -%s", grants)
|
|
155
|
+
logger.info("net %s", net)
|
|
156
|
+
return {"revenue": rev, "grants": grants, "total": net}
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@a_sync.a_sync(default="async")
|
|
160
|
+
async def sum_revenue_transfers(params: Tuple[str, Decimal], timestamp: datetime) -> Decimal:
|
|
161
|
+
wallet, rev_share = params
|
|
162
|
+
block = await get_block_at_timestamp(timestamp)
|
|
163
|
+
total = Decimal(0)
|
|
164
|
+
async for transfer in transfers_for(wallet).yield_thru_block(block):
|
|
165
|
+
transfer = await transfer
|
|
166
|
+
if transfer is None:
|
|
167
|
+
# failed to decode, probably shitcoin
|
|
168
|
+
continue
|
|
169
|
+
if not transfer.value:
|
|
170
|
+
# zero value transfer
|
|
171
|
+
continue
|
|
172
|
+
if transfer.price:
|
|
173
|
+
total += transfer.value * transfer.price
|
|
174
|
+
elif transfer not in _warned and transfer.token not in _known_tokens_without_prices:
|
|
175
|
+
logger.warning(f"BAD: {transfer}")
|
|
176
|
+
_warned.add(transfer)
|
|
177
|
+
return round(total * Decimal((100 - rev_share) / 100), 8)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
async def sum_grants_received(wallet: str, timestamp: datetime) -> Decimal:
|
|
181
|
+
grants = Decimal(0)
|
|
182
|
+
block = await get_block_at_timestamp(timestamp)
|
|
183
|
+
async for transfer in transfers_for(wallet).yield_thru_block(block):
|
|
184
|
+
transfer = await transfer
|
|
185
|
+
if transfer is None:
|
|
186
|
+
# failed to decode, probably shitcoin
|
|
187
|
+
continue
|
|
188
|
+
if not transfer.value:
|
|
189
|
+
# zero value transfer
|
|
190
|
+
continue
|
|
191
|
+
if transfer.price:
|
|
192
|
+
if transfer.from_address != ZERO_ADDRESS:
|
|
193
|
+
try:
|
|
194
|
+
contract = await Contract.coroutine(transfer.from_address)
|
|
195
|
+
if (
|
|
196
|
+
hasattr(contract, "recipient") and await contract.recipient == wallet
|
|
197
|
+
) or transfer.from_address == "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52":
|
|
198
|
+
grants += transfer.value * transfer.price
|
|
199
|
+
except ContractNotVerified as e:
|
|
200
|
+
if str(e) not in _not_verified:
|
|
201
|
+
_not_verified.add(str(e))
|
|
202
|
+
logger.debug(f"{e.__class__.__name__}: {e}")
|
|
203
|
+
except Exception as e:
|
|
204
|
+
logger.warning(f"{e.__class__.__name__}: {e}")
|
|
205
|
+
elif transfer not in _warned and transfer.token not in _known_tokens_without_prices:
|
|
206
|
+
logger.warning(f"BAD: {transfer}")
|
|
207
|
+
_warned.add(transfer)
|
|
208
|
+
return round(grants, 8)
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: yearn_treasury
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.49
|
|
4
4
|
Summary: This WIP library runs the eth-portfolio and dao-treasury exporters for the Yearn Finance treasury.
|
|
5
5
|
Classifier: Development Status :: 3 - Alpha
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
7
7
|
Classifier: Intended Audience :: Science/Research
|
|
8
8
|
Classifier: Intended Audience :: End Users/Desktop
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -16,7 +15,8 @@ Classifier: Operating System :: OS Independent
|
|
|
16
15
|
Classifier: Topic :: Software Development :: Libraries
|
|
17
16
|
Requires-Python: >=3.10,<3.13
|
|
18
17
|
Description-Content-Type: text/markdown
|
|
19
|
-
Requires-Dist: dao-treasury
|
|
18
|
+
Requires-Dist: dao-treasury==0.0.72
|
|
19
|
+
Requires-Dist: faster-async-lru<3,>=2.0.5
|
|
20
20
|
Dynamic: classifier
|
|
21
21
|
Dynamic: description
|
|
22
22
|
Dynamic: description-content-type
|