yearn-treasury 0.0.15__cp311-cp311-win_amd64.whl → 0.1.3__cp311-cp311-win_amd64.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.

Files changed (108) hide show
  1. yearn_treasury/__init__.py +12 -0
  2. yearn_treasury/_db.cp311-win_amd64.pyd +0 -0
  3. yearn_treasury/_db.py +39 -10
  4. yearn_treasury/_ens.cp311-win_amd64.pyd +0 -0
  5. yearn_treasury/_ens.py +14 -0
  6. yearn_treasury/_logging.cp311-win_amd64.pyd +0 -0
  7. yearn_treasury/_logging.py +43 -0
  8. yearn_treasury/{addresses.yaml → address_labels.yaml} +10 -0
  9. yearn_treasury/budget/__init__.cp311-win_amd64.pyd +0 -0
  10. yearn_treasury/budget/__init__.py +2 -2
  11. yearn_treasury/budget/_request.cp311-win_amd64.pyd +0 -0
  12. yearn_treasury/budget/_request.py +8 -0
  13. yearn_treasury/budget/_requests.cp311-win_amd64.pyd +0 -0
  14. yearn_treasury/budget/_requests.py +45 -14
  15. yearn_treasury/constants.py +27 -7
  16. yearn_treasury/main.py +71 -29
  17. yearn_treasury/rules/__init__.py +14 -0
  18. yearn_treasury/rules/constants.cp311-win_amd64.pyd +0 -0
  19. yearn_treasury/rules/cost_of_revenue/gas.cp311-win_amd64.pyd +0 -0
  20. yearn_treasury/rules/cost_of_revenue/gas.py +9 -1
  21. yearn_treasury/rules/expense/__init__.cp311-win_amd64.pyd +0 -0
  22. yearn_treasury/rules/expense/general.cp311-win_amd64.pyd +0 -0
  23. yearn_treasury/rules/expense/infrastructure.cp311-win_amd64.pyd +0 -0
  24. yearn_treasury/rules/expense/infrastructure.py +7 -0
  25. yearn_treasury/rules/expense/people.cp311-win_amd64.pyd +0 -0
  26. yearn_treasury/rules/expense/people.py +43 -0
  27. yearn_treasury/rules/expense/security.cp311-win_amd64.pyd +0 -0
  28. yearn_treasury/rules/expense/security.py +17 -0
  29. yearn_treasury/rules/ignore/__init__.py +2 -0
  30. yearn_treasury/rules/ignore/general.cp311-win_amd64.pyd +0 -0
  31. yearn_treasury/rules/ignore/general.py +3 -2
  32. yearn_treasury/rules/ignore/maker.py +40 -28
  33. yearn_treasury/rules/ignore/passthru.py +310 -0
  34. yearn_treasury/rules/ignore/swaps/__init__.py +14 -0
  35. yearn_treasury/rules/ignore/swaps/aave.py +39 -18
  36. yearn_treasury/rules/ignore/swaps/auctions.cp311-win_amd64.pyd +0 -0
  37. yearn_treasury/rules/ignore/swaps/auctions.py +31 -0
  38. yearn_treasury/rules/ignore/swaps/compound.py +32 -22
  39. yearn_treasury/rules/ignore/swaps/conversion_factory.cp311-win_amd64.pyd +0 -0
  40. yearn_treasury/rules/ignore/swaps/conversion_factory.py +21 -0
  41. yearn_treasury/rules/ignore/swaps/cowswap.py +87 -0
  42. yearn_treasury/rules/ignore/swaps/curve.py +170 -0
  43. yearn_treasury/rules/ignore/swaps/gearbox.cp311-win_amd64.pyd +0 -0
  44. yearn_treasury/rules/ignore/swaps/gearbox.py +37 -0
  45. yearn_treasury/rules/ignore/swaps/iearn.cp311-win_amd64.pyd +0 -0
  46. yearn_treasury/rules/ignore/swaps/iearn.py +43 -0
  47. yearn_treasury/rules/ignore/swaps/otc.cp311-win_amd64.pyd +0 -0
  48. yearn_treasury/rules/ignore/swaps/otc.py +58 -0
  49. yearn_treasury/rules/ignore/swaps/pooltogether.cp311-win_amd64.pyd +0 -0
  50. yearn_treasury/rules/ignore/swaps/pooltogether.py +23 -0
  51. yearn_treasury/rules/ignore/swaps/synthetix.cp311-win_amd64.pyd +0 -0
  52. yearn_treasury/rules/ignore/swaps/synthetix.py +10 -0
  53. yearn_treasury/rules/ignore/swaps/uniswap.py +29 -6
  54. yearn_treasury/rules/ignore/swaps/unwrapper.cp311-win_amd64.pyd +0 -0
  55. yearn_treasury/rules/ignore/swaps/unwrapper.py +17 -0
  56. yearn_treasury/rules/ignore/swaps/vaults.cp311-win_amd64.pyd +0 -0
  57. yearn_treasury/rules/ignore/swaps/vaults.py +264 -0
  58. yearn_treasury/rules/ignore/swaps/woofy.cp311-win_amd64.pyd +0 -0
  59. yearn_treasury/rules/ignore/swaps/woofy.py +80 -0
  60. yearn_treasury/rules/ignore/swaps/yfi.cp311-win_amd64.pyd +0 -0
  61. yearn_treasury/rules/ignore/swaps/yfi.py +111 -0
  62. yearn_treasury/rules/ignore/swaps/yla.cp311-win_amd64.pyd +0 -0
  63. yearn_treasury/rules/ignore/swaps/yla.py +28 -0
  64. yearn_treasury/rules/ignore/unit.cp311-win_amd64.pyd +0 -0
  65. yearn_treasury/rules/ignore/unit.py +40 -0
  66. yearn_treasury/rules/ignore/weth.cp311-win_amd64.pyd +0 -0
  67. yearn_treasury/rules/ignore/weth.py +12 -4
  68. yearn_treasury/rules/ignore/ygov.cp311-win_amd64.pyd +0 -0
  69. yearn_treasury/rules/other_expense/__init__.cp311-win_amd64.pyd +0 -0
  70. yearn_treasury/rules/other_expense/__init__.py +1 -0
  71. yearn_treasury/rules/other_expense/boost.cp311-win_amd64.pyd +0 -0
  72. yearn_treasury/rules/other_expense/bugs.cp311-win_amd64.pyd +0 -0
  73. yearn_treasury/rules/other_expense/donations.cp311-win_amd64.pyd +0 -0
  74. yearn_treasury/rules/other_expense/donations.py +43 -0
  75. yearn_treasury/rules/other_expense/dyfi.cp311-win_amd64.pyd +0 -0
  76. yearn_treasury/rules/other_expense/events.cp311-win_amd64.pyd +0 -0
  77. yearn_treasury/rules/other_expense/events.py +6 -0
  78. yearn_treasury/rules/other_expense/match_on_to_address.yaml +3 -2
  79. yearn_treasury/rules/other_expense/misc.cp311-win_amd64.pyd +0 -0
  80. yearn_treasury/rules/other_expense/misc.py +22 -0
  81. yearn_treasury/rules/other_expense/revshare.cp311-win_amd64.pyd +0 -0
  82. yearn_treasury/rules/other_income/__init__.cp311-win_amd64.pyd +0 -0
  83. yearn_treasury/rules/other_income/__init__.py +2 -77
  84. yearn_treasury/rules/other_income/airdrops.cp311-win_amd64.pyd +0 -0
  85. yearn_treasury/rules/other_income/airdrops.py +30 -0
  86. yearn_treasury/rules/other_income/match_on_hash.yaml +2 -0
  87. yearn_treasury/rules/other_income/misc.cp311-win_amd64.pyd +0 -0
  88. yearn_treasury/rules/other_income/misc.py +80 -0
  89. yearn_treasury/rules/revenue/bribes.cp311-win_amd64.pyd +0 -0
  90. yearn_treasury/rules/revenue/farming.cp311-win_amd64.pyd +0 -0
  91. yearn_treasury/rules/revenue/keepcoins.cp311-win_amd64.pyd +0 -0
  92. yearn_treasury/rules/revenue/seasolver.cp311-win_amd64.pyd +0 -0
  93. yearn_treasury/rules/revenue/vaults.py +25 -22
  94. yearn_treasury/rules/revenue/yteams.cp311-win_amd64.pyd +0 -0
  95. yearn_treasury/shitcoins.py +93 -2
  96. yearn_treasury/vaults.cp311-win_amd64.pyd +0 -0
  97. yearn_treasury/vaults.py +17 -4
  98. yearn_treasury/wallets.yaml +54 -0
  99. yearn_treasury/yteams.py +208 -0
  100. {yearn_treasury-0.0.15.dist-info → yearn_treasury-0.1.3.dist-info}/METADATA +21 -8
  101. yearn_treasury-0.1.3.dist-info/RECORD +128 -0
  102. yearn_treasury-0.1.3.dist-info/top_level.txt +2 -0
  103. yearn_treasury__mypyc.cp311-win_amd64.pyd +0 -0
  104. 3ddd27aee2f79379b6d9__mypyc.cp311-win_amd64.pyd +0 -0
  105. yearn_treasury-0.0.15.dist-info/RECORD +0 -85
  106. yearn_treasury-0.0.15.dist-info/top_level.txt +0 -2
  107. {yearn_treasury-0.0.15.dist-info → yearn_treasury-0.1.3.dist-info}/WHEEL +0 -0
  108. {yearn_treasury-0.0.15.dist-info → yearn_treasury-0.1.3.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
 
@@ -25,3 +33,17 @@ def is_ybudget_reward(tx: TreasuryTx) -> bool:
25
33
  "0x6ba3f2bed8b766ed2185df1a492b3ecab0251747c619a5d60e7401908120c9c8",
26
34
  )
27
35
  )
36
+
37
+
38
+ @other_expense("1 YFI for Signers", Network.Mainnet)
39
+ def is_one_yfi_for_signers(tx: TreasuryTx) -> bool:
40
+ txhash = tx.hash
41
+ return txhash in (
42
+ "0x86700207761cdca82a0ad4e04b49b749913de63c8bd933b4f3f9a145d9b2c1fa",
43
+ # https://snapshot.box/#/s:veyfi.eth/proposal/0xc7ded2863a10154b6b520921af4ada48d64d74e5b7989f98cdf073542b2e4411
44
+ "0x5ed4ce821cb09b4c6929cc9a6b5e0a23515f9bb97d9b5916819a6986f6c89f09",
45
+ "0xe80628d90254f8da0a6016629c8811b5dd54f231e94f71697ab37d8c00482586",
46
+ ) or (
47
+ txhash == "0x831ad751e1be1dbb82cb9e1f5bf0e38e31327b8c58f6ad6b90bcfb396129bb11"
48
+ and tx.log_index == 403
49
+ )
@@ -1,77 +1,2 @@
1
- from decimal import Decimal
2
- from typing import Final
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("aToken Yield", Network.Mainnet)
14
- def is_atoken_yield(tx: TreasuryTx) -> bool:
15
- return (
16
- tx.symbol in ("aLEND", "aLINK")
17
- and tx.from_address.address == ZERO_ADDRESS
18
- and tx.to_nickname in ("Yearn Treasury", "Yearn Treasury V1")
19
- )
20
-
21
-
22
- @other_income("RoboVault Thank You", Network.Fantom)
23
- async def is_robovault_share(tx: TreasuryTx) -> bool:
24
- """
25
- After Yearn devs helped robovault with a vulnerability, robovault committed to sending Yearn a portion of their fees.
26
- """
27
- if not tx.symbol.startswith("rv") and tx.from_address.is_contract:
28
- return False
29
-
30
- try:
31
- strat = await Contract.coroutine(tx.from_address.address)
32
- except ContractNotVerified:
33
- return False
34
-
35
- if not hasattr(strat, "vault"):
36
- return False
37
-
38
- if await strat.vault.coroutine(block_identifier=tx.block) == tx.token:
39
- return True
40
-
41
- return (
42
- tx.from_nickname == "Contract: Strategy"
43
- and tx.symbol == "rv3USDCc"
44
- and await ERC20( # type: ignore [call-overload]
45
- await strat.vault.coroutine(block_identifier=tx.block),
46
- asynchronous=True,
47
- ).symbol
48
- == "rv3USDCb"
49
- )
50
-
51
-
52
- @other_income("Cowswap Gas Reimbursement", Network.Mainnet)
53
- def is_cowswap_gas_reimbursement(tx: TreasuryTx) -> bool:
54
- return (
55
- tx.symbol == "ETH"
56
- and tx.from_nickname == "Cowswap Multisig"
57
- and tx.to_nickname == "yMechs Multisig"
58
- )
59
-
60
-
61
- @other_income("USDS Referral Code", Network.Mainnet)
62
- def is_usds_referral_code(tx: TreasuryTx) -> bool:
63
- """Yearn earns some USDS for referring deposits to Maker"""
64
- return (
65
- tx.symbol == "USDS"
66
- and tx.from_address.address == "0x3C5142F28567E6a0F172fd0BaaF1f2847f49D02F"
67
- )
68
-
69
-
70
- @other_income("yETH Application Fee", Network.Mainnet)
71
- def is_yeth_application_fee(tx: TreasuryTx) -> bool:
72
- return tx.symbol == "yETH" and tx.to_nickname == "Yearn Treasury" and tx.amount == _POINT_ONE
73
-
74
-
75
- @other_income("yPRISMA Fees", Network.Mainnet)
76
- def is_yprisma_fees(tx: TreasuryTx) -> bool:
77
- 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 *
@@ -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
+ }
@@ -1,4 +1,6 @@
1
1
  1:
2
+ YFI Mint:
3
+ - "0x21a3007a2547a9d6f1bceb44cb9292b36079fcccd8f36f7ec1ca066db261e153"
2
4
  yvUSDN Shutdown:
3
5
  # The USDN vault was shut down but the pool was so rekt they coulnd't even swap for want. Trace amounts of yield sent to yChad.
4
6
  - "0x12b3687f4bfbc73c11dccbd61d18c3f785e6f0f91cb46280d7df08143162ceed"
@@ -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"
@@ -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.token.address.address
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)
@@ -74,19 +75,20 @@ async def is_v1_vault_fees(tx: TreasuryTx) -> bool:
74
75
  strategy: ChecksumAddress = await controller.strategies.coroutine(
75
76
  underlying, block_identifier=tx.block
76
77
  )
77
- if tx.from_address != strategy:
78
- logger.debug(
79
- "from address %s doesnt match strategy %s set on controller %s",
80
- tx.from_address.address,
81
- strategy,
82
- controller,
83
- )
84
- continue
85
- return True
78
+ if tx.from_address == strategy:
79
+ return True
80
+ logger.debug(
81
+ "from address %s doesnt match strategy %s set on controller %s",
82
+ tx.from_address.address,
83
+ strategy,
84
+ controller,
85
+ )
86
86
  return False
87
87
 
88
88
 
89
- def is_inverse_fees_from_stash_contract(from_address: str, to_nickname: str) -> bool:
89
+ def is_inverse_fees_from_stash_contract(
90
+ from_address: ChecksumAddress, to_nickname: str | None
91
+ ) -> bool:
90
92
  return (
91
93
  from_address == "0xE376e8e8E3B0793CD61C6F1283bA18548b726C2e"
92
94
  and to_nickname == "Token: Curve stETH Pool yVault"
@@ -95,18 +97,19 @@ def is_inverse_fees_from_stash_contract(from_address: str, to_nickname: str) ->
95
97
 
96
98
  @fees("Vaults V2")
97
99
  async def is_v2_vault_fees(tx: TreasuryTx) -> bool:
98
- token = tx.token.address.address
99
- from_address = tx.from_address.address
100
+ token = tx.token_address
101
+ from_address = cast(ChecksumAddress, tx.from_address.address)
100
102
  if (
101
103
  from_address == token
102
- and (vault := v2.get(from_address)) # type: ignore [arg-type]
104
+ and (vault := v2.get(from_address))
103
105
  and tx.to_address == await vault.rewards.coroutine(block_identifier=tx.block)
104
106
  ):
105
107
  return True
106
108
 
107
- if is_inverse_fees_from_stash_contract(from_address, tx.to_nickname): # type: ignore [arg-type]
108
- if tx.value_usd > 0: # type: ignore [operator]
109
- tx.value_usd *= -1 # type: ignore [operator]
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
110
113
  return True
111
114
 
112
115
  return False
@@ -118,7 +121,7 @@ def is_v3_vault_fees(tx: TreasuryTx) -> bool:
118
121
  return False
119
122
 
120
123
 
121
- @fees("YearnFed Fees", Network.Mainnet)
124
+ @fees("YearnFed", Network.Mainnet)
122
125
  def is_yearn_fed_fees(tx: TreasuryTx) -> bool:
123
126
  symbol = tx.symbol
124
127
  from_address = tx.from_address
@@ -148,7 +151,7 @@ def is_yearn_fed_fees(tx: TreasuryTx) -> bool:
148
151
  return False
149
152
 
150
153
 
151
- @fees("DOLAFRAXBP Fees", Network.Mainnet)
154
+ @fees("DOLAFRAXBP", Network.Mainnet)
152
155
  def is_dolafraxbp_fees(tx: TreasuryTx) -> bool:
153
156
  return (
154
157
  tx.from_nickname == "Contract: StrategyConvexFraxBpRewardsClonable"
@@ -157,7 +160,7 @@ def is_dolafraxbp_fees(tx: TreasuryTx) -> bool:
157
160
  )
158
161
 
159
162
 
160
- @fees("TempleDAO Private Vault Fees", Network.Mainnet)
163
+ @fees("TempleDAO Private Vault", Network.Mainnet)
161
164
  def is_temple(tx: TreasuryTx) -> bool:
162
165
  if tx.to_nickname in ["Yearn Treasury", "Yearn yChad Multisig"]: # fees have been sent to both
163
166
  from_nickname = tx.from_nickname
@@ -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,18 +50,93 @@ _SHITCOINS = {
34
50
  "0xe5868468Cb6Dd5d6D7056bd93f084816c6eF075f",
35
51
  "0x0a24Bb4842c301276c65086B5d78D5C872993c72",
36
52
  "0x63125c0d5Cd9071de9A1ac84c400982f41C697AE",
53
+ "0x4d22921215cF37e8d49e2Ac6d1F5e9672f63A7c6",
54
+ "0xe2549E429B78458fa60BC7B1b284d4411E1D5105",
55
+ "0xCfdD747d041397bcE08B0Fe6ebF7Ef65E9F46795",
56
+ "0x9745969171a38B40db05c506fe2DA2C36f317627",
57
+ "0x6051C1354Ccc51b4d561e43b02735DEaE64768B8",
58
+ "0xf0814d0E47F2390a8082C4a1BD819FDDe50f9bFc",
59
+ "0x2DBd330bC9B7f3A822a9173aB52172BdDDcAcE2A",
60
+ # just andre tinkering
61
+ "0x5cB5e2d7Ab9Fd32021dF8F1D3E5269bD437Ec3Bf",
37
62
  # these arent shitcoins per se but we can't price them and dont expect to in the future, lets save cpu cycles
38
63
  "0x9d45DAb69f1309F1F55A7280b1f6a2699ec918E8", # yFamily NFT <3
39
64
  "0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85", # ENS
40
65
  "0xD057B63f5E69CF1B929b356b579Cba08D7688048", # vCOW
41
66
  "0x4c1317326fD8EFDeBdBE5e1cd052010D97723bd6", # deprecated yCRV
42
67
  "0x8a0889d47f9Aa0Fac1cC718ba34E26b867437880", # deprecated st-yCRV
68
+ "0x55a290f08Bb4CAe8DcF1Ea5635A3FCfd4Da60456", # BITTO
69
+ "0x4770F3186225b1A6879983BD88C669CA55463886", # 69XMins
70
+ "0x05bAdF8A8e7fE5b43fae112108E26f2f663Bf1a2", # INUNOMICS
71
+ "0x3EF9181c9b96BAAafb3717A553E808Ccc72be37D", # MEMEPEPE
72
+ "0x5D22c8b4E3c90ca633e1377e6ca280a395fc61C0", # XMEME
73
+ "0x57f19E7e1A9066a741f59484481C4D2E9150e9E2", # MOCO
74
+ "0xb092D8E13Ba50963D57bEcB17a037728D883D02d", # BABYLABUBU
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
43
88
  # test token?
44
89
  "0x372d5d02c6b4075bd58892f80300cA590e92d29E", # tOUSG
45
90
  # dETH? don't think this is needed
46
91
  "0x3d1E5Cf16077F349e999d6b21A4f646e83Cd90c5",
92
+ # ai shitcoin spam
93
+ "0xaf80B7dbeBbb5d9a4d33C453FcbF3d054DA53b25", # NODEPAY AI
94
+ "0xf960AbF9ccC883970BEa3E79f65027E27278e1A5", # ASK AI
95
+ "0xc136Eb8Abc892723aE87F355d12Cb721C4324D54", # Grok3
96
+ "0xc68bCEE3604F163f183Cf8B9a26E610E5961b037", # TESLA AI
97
+ "0xa65D56f8e074E773142205cD065FD0796B9aa483", # MASSIVE AI
98
+ "0x4e6c80aa486aF0ba20943Fbc067a5557DBcf5458", # SUNO AI
99
+ "0xC91223F844772dCdc2c6394585C8c30B3c1BE5C0", # SEND AI
100
+ "0x64b3336D1aDC6D3579e356760F53D3b018Cb11Bc", # ALC AI
101
+ "0x1495Ac869433698cCD2946c1e62D37bA766294A9", # NVIDIA AI PC
102
+ "0x8c0DF275c38092cd90Ae4d6147d8e619B3A24637", # COLLE AI
103
+ "0xe38f71fc2Ca5f5761cE21F39Fff2cE70662FA54c", # CHAINOPERA AI
104
+ "0xD2F89F59fBC7125b406e3F60A992DFa9FdB76524", # MISTRAL AI
105
+ "0xa0CCdBCeB5Da30F9d62F7A727F2B35C69dF08760", # CHUNK AI
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
117
+ # matt furry spam
118
+ "0x73228b3D33cC71cB721Fc62950577bE63bd9c8C9", # Maskman by Matt Furie
119
+ "0x7c28e66436C93BB9F657dDF2BA0eeeCf61369b92", # Bloodboy by Matt Furie
120
+ "0x70c5e1124569f17B1Be71E15833EaF1331f8727F", # Pac-hat by Matt Furie
121
+ "0xBd6555eC87C8A9a2280dCD6df45b9b074fC93Df2", # Bork by Matt Furie
122
+ # test token
123
+ "0x2F375Ce83EE85e505150d24E85A1742fd03cA593", # TEST
47
124
  ),
48
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
+
49
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.
50
138
 
51
- SHITCOINS = {convert.to_address(shitcoin) for shitcoin in _SHITCOINS.get(CHAINID, ())} # type: ignore [call-overload]
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
- from typing import Dict, Final, List
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() # type: ignore [attr-defined]
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) # type: ignore [index]
50
+ v2[vault_address] = Contract(vault_address)
@@ -0,0 +1,54 @@
1
+ # Treasury
2
+ "0x93A62dA5a14C80f265DAbC077fCEE437B1a0Efde":
3
+ networks:
4
+ - 1
5
+ "0x89716Ad7EDC3be3B35695789C475F3e7A3Deb12a":
6
+ networks:
7
+ - 250
8
+
9
+ # yChad
10
+ "0xFEB4acf3df3cDEA7399794D0869ef76A6EfAff52":
11
+ networks:
12
+ - 1
13
+ "0xC0E2830724C946a6748dDFE09753613cd38f6767":
14
+ networks:
15
+ - 250
16
+
17
+ # Yearn Treasury V1
18
+ "0xb99a40fcE04cb740EB79fC04976CA15aF69AaaaE":
19
+ networks:
20
+ - 1
21
+
22
+ # Yearn KP3R Wallet
23
+ "0x5f0845101857d2A91627478e302357860b1598a1":
24
+
25
+ # ySwap Multisig
26
+ "0x7d2aB9CA511EBD6F03971Fb417d3492aA82513f0":
27
+
28
+ # yMechs Multisig
29
+ "0x2C01B4AD51a67E2d8F02208F54dF9aC4c0B778B6":
30
+ end:
31
+ block:
32
+ 1: 17162286
33
+
34
+ # Fee Reimbursement Stash
35
+ "0xE376e8e8E3B0793CD61C6F1283bA18548b726C2e":
36
+
37
+ # New token dumping wallet
38
+ "0xC001d00d425Fa92C4F840baA8f1e0c27c4297a0B":
39
+
40
+ # veFarming wallet
41
+ "0x4fc1b14cD213e7B6212145Ba4f180C3d53d1A11e":
42
+
43
+ ### yRoboTreasury Wallets ###
44
+ # https://github.com/yearn/yRoboTreasury/blob/master/deployment.json
45
+
46
+ # Treasury
47
+ "0xEf77cc176c748d291EfB6CdC982c5744fC7211c8":
48
+ networks:
49
+ - 1
50
+
51
+ # Stables reserve
52
+ "0x278374fFb10B7D16E7633444c13e6E565EA57c28":
53
+ networks:
54
+ - 1