yearn-treasury 0.0.18__cp310-cp310-win32.whl → 0.0.46__cp310-cp310-win32.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.cp310-win32.pyd +0 -0
- yearn_treasury/_db.py +21 -0
- yearn_treasury/_ens.cp310-win32.pyd +0 -0
- yearn_treasury/_ens.py +14 -0
- yearn_treasury/_logging.cp310-win32.pyd +0 -0
- yearn_treasury/_logging.py +43 -0
- yearn_treasury/address_labels.yaml +10 -0
- yearn_treasury/budget/__init__.cp310-win32.pyd +0 -0
- yearn_treasury/budget/__init__.py +2 -2
- yearn_treasury/budget/_request.cp310-win32.pyd +0 -0
- yearn_treasury/budget/_request.py +8 -0
- yearn_treasury/budget/_requests.cp310-win32.pyd +0 -0
- yearn_treasury/budget/_requests.py +44 -17
- yearn_treasury/constants.py +20 -2
- yearn_treasury/main.py +54 -20
- yearn_treasury/rules/__init__.py +14 -0
- yearn_treasury/rules/constants.cp310-win32.pyd +0 -0
- yearn_treasury/rules/cost_of_revenue/gas.cp310-win32.pyd +0 -0
- yearn_treasury/rules/cost_of_revenue/gas.py +9 -1
- yearn_treasury/rules/expense/__init__.cp310-win32.pyd +0 -0
- yearn_treasury/rules/expense/general.cp310-win32.pyd +0 -0
- yearn_treasury/rules/expense/infrastructure.cp310-win32.pyd +0 -0
- yearn_treasury/rules/expense/infrastructure.py +7 -0
- yearn_treasury/rules/expense/people.cp310-win32.pyd +0 -0
- yearn_treasury/rules/expense/people.py +43 -0
- yearn_treasury/rules/expense/security.cp310-win32.pyd +0 -0
- yearn_treasury/rules/expense/security.py +17 -0
- yearn_treasury/rules/ignore/__init__.py +1 -0
- yearn_treasury/rules/ignore/general.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/maker.py +40 -28
- yearn_treasury/rules/ignore/passthru.py +172 -12
- yearn_treasury/rules/ignore/swaps/__init__.py +14 -0
- yearn_treasury/rules/ignore/swaps/aave.py +39 -18
- yearn_treasury/rules/ignore/swaps/auctions.cp310-win32.pyd +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.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/conversion_factory.py +21 -0
- yearn_treasury/rules/ignore/swaps/cowswap.py +87 -0
- yearn_treasury/rules/ignore/swaps/curve.py +170 -0
- yearn_treasury/rules/ignore/swaps/gearbox.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/gearbox.py +37 -0
- yearn_treasury/rules/ignore/swaps/iearn.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/iearn.py +43 -0
- yearn_treasury/rules/ignore/swaps/otc.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/otc.py +58 -0
- yearn_treasury/rules/ignore/swaps/pooltogether.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/pooltogether.py +23 -0
- yearn_treasury/rules/ignore/swaps/synthetix.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/synthetix.py +10 -0
- yearn_treasury/rules/ignore/swaps/uniswap.py +29 -6
- yearn_treasury/rules/ignore/swaps/unwrapper.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/unwrapper.py +17 -0
- yearn_treasury/rules/ignore/swaps/vaults.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/vaults.py +264 -0
- yearn_treasury/rules/ignore/swaps/woofy.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/woofy.py +80 -0
- yearn_treasury/rules/ignore/swaps/yfi.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/yfi.py +111 -0
- yearn_treasury/rules/ignore/swaps/yla.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/swaps/yla.py +28 -0
- yearn_treasury/rules/ignore/unit.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/unit.py +40 -0
- yearn_treasury/rules/ignore/weth.cp310-win32.pyd +0 -0
- yearn_treasury/rules/ignore/weth.py +12 -4
- yearn_treasury/rules/ignore/ygov.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_expense/__init__.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_expense/boost.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_expense/bugs.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_expense/donations.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_expense/donations.py +8 -0
- yearn_treasury/rules/other_expense/dyfi.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_expense/events.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_expense/misc.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_expense/misc.py +22 -0
- yearn_treasury/rules/other_expense/revshare.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_income/__init__.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_income/__init__.py +2 -100
- yearn_treasury/rules/other_income/airdrops.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_income/airdrops.py +30 -0
- yearn_treasury/rules/other_income/match_on_hash.yaml +2 -0
- yearn_treasury/rules/other_income/misc.cp310-win32.pyd +0 -0
- yearn_treasury/rules/other_income/misc.py +80 -0
- yearn_treasury/rules/revenue/bribes.cp310-win32.pyd +0 -0
- yearn_treasury/rules/revenue/farming.cp310-win32.pyd +0 -0
- yearn_treasury/rules/revenue/keepcoins.cp310-win32.pyd +0 -0
- yearn_treasury/rules/revenue/seasolver.cp310-win32.pyd +0 -0
- yearn_treasury/rules/revenue/vaults.py +14 -10
- yearn_treasury/rules/revenue/yteams.cp310-win32.pyd +0 -0
- yearn_treasury/shitcoins.py +92 -2
- yearn_treasury/vaults.cp310-win32.pyd +0 -0
- yearn_treasury/vaults.py +17 -4
- yearn_treasury/wallets.yaml +14 -1
- yearn_treasury/yteams.py +208 -0
- {yearn_treasury-0.0.18.dist-info → yearn_treasury-0.0.46.dist-info}/METADATA +3 -3
- yearn_treasury-0.0.46.dist-info/RECORD +128 -0
- yearn_treasury-0.0.46.dist-info/top_level.txt +2 -0
- yearn_treasury__mypyc.cp310-win32.pyd +0 -0
- 5f18f6d379e6cea9f0c7__mypyc.cp310-win32.pyd +0 -0
- yearn_treasury-0.0.18.dist-info/RECORD +0 -93
- yearn_treasury-0.0.18.dist-info/top_level.txt +0 -2
- {yearn_treasury-0.0.18.dist-info → yearn_treasury-0.0.46.dist-info}/WHEEL +0 -0
- {yearn_treasury-0.0.18.dist-info → yearn_treasury-0.0.46.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
from typing import Final
|
|
2
|
+
|
|
3
|
+
from brownie.exceptions import EventLookupError
|
|
4
|
+
from brownie.network.event import _EventItem
|
|
5
|
+
from dao_treasury import TreasuryTx, TreasuryWallet
|
|
6
|
+
from eth_typing import ChecksumAddress
|
|
7
|
+
from faster_async_lru import alru_cache
|
|
8
|
+
from y import Contract, Network
|
|
9
|
+
|
|
10
|
+
from yearn_treasury.constants import CHAINID, ZERO_ADDRESS
|
|
11
|
+
from yearn_treasury.rules.ignore.swaps import swaps
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
curve: Final = swaps("Curve")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# curve helpers
|
|
18
|
+
@alru_cache(maxsize=None)
|
|
19
|
+
async def _get_lp_token(pool: Contract) -> ChecksumAddress:
|
|
20
|
+
return ChecksumAddress(await pool.lp_token)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
async def _is_old_style(tx: TreasuryTx, pool: Contract) -> bool:
|
|
24
|
+
return hasattr(pool, "lp_token") and tx.token == await _get_lp_token(pool)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _is_new_style(tx: TreasuryTx, pool: Contract) -> bool:
|
|
28
|
+
return hasattr(pool, "totalSupply") and tx.token == pool.address
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _token_is_curvey(tx: TreasuryTx) -> bool:
|
|
32
|
+
return "crv" in tx.symbol.lower() or "curve" in tx.token.name.lower()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@alru_cache(maxsize=None)
|
|
36
|
+
async def _get_coin_at_index(pool: Contract, index: int) -> ChecksumAddress:
|
|
37
|
+
return ChecksumAddress(await pool.coins.coroutine(index))
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@curve("Adding Liquidity")
|
|
41
|
+
async def is_curve_deposit(tx: TreasuryTx) -> bool:
|
|
42
|
+
pool: Contract
|
|
43
|
+
for event in tx.get_events("AddLiquidity"):
|
|
44
|
+
# LP Token Side
|
|
45
|
+
if tx.from_address == ZERO_ADDRESS and _token_is_curvey(tx):
|
|
46
|
+
pool = await Contract.coroutine(event.address) # type: ignore [assignment]
|
|
47
|
+
if await _is_old_style(tx, pool) or _is_new_style(tx, pool):
|
|
48
|
+
return True
|
|
49
|
+
|
|
50
|
+
# Tokens sent
|
|
51
|
+
elif tx.to_address == event.address:
|
|
52
|
+
try:
|
|
53
|
+
tx_amount = round(tx.amount, 8)
|
|
54
|
+
for i, amount in enumerate(event["token_amounts"]):
|
|
55
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
56
|
+
event_amount = round(tx.token.scale_value(amount), 8)
|
|
57
|
+
if tx_amount == event_amount:
|
|
58
|
+
pool = await Contract.coroutine(event.address) # type: ignore [assignment]
|
|
59
|
+
if tx.token == await _get_coin_at_index(pool, i):
|
|
60
|
+
return True
|
|
61
|
+
return True
|
|
62
|
+
else:
|
|
63
|
+
print(
|
|
64
|
+
f"Curve AddLiquidity sent amount does not match: {tx_amount} {event_amount}"
|
|
65
|
+
)
|
|
66
|
+
except EventLookupError:
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
# What if a 3crv deposit was needed before the real deposit?
|
|
70
|
+
elif (
|
|
71
|
+
TreasuryWallet.check_membership(tx.from_address.address, tx.block) # type: ignore [union-attr, arg-type]
|
|
72
|
+
and tx.to_address == "0xA79828DF1850E8a3A3064576f380D90aECDD3359"
|
|
73
|
+
and event.address == "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7"
|
|
74
|
+
):
|
|
75
|
+
print(f"AddLiquidity-3crv: {event}")
|
|
76
|
+
token = tx.token
|
|
77
|
+
for i, amount in enumerate(event["token_amounts"]):
|
|
78
|
+
event_amount = token.scale_value(amount)
|
|
79
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
80
|
+
if round(tx.amount, 14) == round(event_amount, 14):
|
|
81
|
+
pool = await Contract.coroutine(event.address) # type: ignore [assignment]
|
|
82
|
+
if token == await _get_coin_at_index(pool, i):
|
|
83
|
+
return True
|
|
84
|
+
else:
|
|
85
|
+
print(
|
|
86
|
+
f"AddLiquidity-3crv amount does not match: {round(tx.amount, 14)} {round(event_amount)}"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
# TODO: see if we can remove these with latest hueristics
|
|
90
|
+
return CHAINID == Network.Mainnet and tx.hash in (
|
|
91
|
+
"0x567d2ebc1a336185950432b8f8b010e1116936f9e6c061634f5aba65bdb1e188",
|
|
92
|
+
"0x17e2d7a40697204b3e726d40725082fec5f152f65f400df850f13ef4a4f6c827",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@curve("Removing Liquidity")
|
|
97
|
+
async def is_curve_withdrawal(tx: TreasuryTx) -> bool:
|
|
98
|
+
return (
|
|
99
|
+
_is_curve_withdrawal_one(tx)
|
|
100
|
+
or await _is_curve_withdrawal_multi(tx)
|
|
101
|
+
or (
|
|
102
|
+
CHAINID == Network.Mainnet
|
|
103
|
+
and tx.hash
|
|
104
|
+
in (
|
|
105
|
+
# This was a one-off withdrawal from a special pool 0x5756bbdDC03DaB01a3900F01Fb15641C3bfcc457
|
|
106
|
+
"0xe4f7c8566944202faed1d1e190e400e7bdf8592e65803b09510584ca5284d174",
|
|
107
|
+
)
|
|
108
|
+
)
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _is_curve_withdrawal_one(tx: TreasuryTx) -> bool:
|
|
113
|
+
for event in tx.get_events("RemoveLiquidityOne"):
|
|
114
|
+
# LP Token Side
|
|
115
|
+
if tx.to_address == ZERO_ADDRESS and _token_is_curvey(tx):
|
|
116
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
117
|
+
event_amount = round(tx.token.scale_value(event["token_amount"]), 9)
|
|
118
|
+
if round(tx.amount, 9) == event_amount:
|
|
119
|
+
return True
|
|
120
|
+
print(
|
|
121
|
+
f"Curve withdrawal one curvey amount does not match: {round(tx.amount, 9)} {event_amount}"
|
|
122
|
+
)
|
|
123
|
+
# Tokens rec'd
|
|
124
|
+
if tx.from_address != event.address:
|
|
125
|
+
continue
|
|
126
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
127
|
+
event_amount = tx.token.scale_value(event["coin_amount"])
|
|
128
|
+
if round(tx.amount, 9) == round(event_amount, 9):
|
|
129
|
+
return True
|
|
130
|
+
print(
|
|
131
|
+
f"Curve withdrawal one amount does not match: {round(tx.amount, 9)} {round(event_amount, 9)}"
|
|
132
|
+
)
|
|
133
|
+
return False
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
async def _is_curve_withdrawal_multi(tx: TreasuryTx) -> bool:
|
|
137
|
+
pool: Contract
|
|
138
|
+
for event in tx.get_events("RemoveLiquidity"):
|
|
139
|
+
# LP Token side
|
|
140
|
+
if tx.to_address == ZERO_ADDRESS and _token_is_curvey(tx):
|
|
141
|
+
pool = await Contract.coroutine(event.address) # type: ignore [assignment]
|
|
142
|
+
if await _is_old_style(tx, pool) or _is_new_style(tx, pool):
|
|
143
|
+
return True
|
|
144
|
+
print(
|
|
145
|
+
f"unhandled curve pool: {tx} symbol={tx.symbol} name={tx.token.name} address={tx.token_address}"
|
|
146
|
+
)
|
|
147
|
+
# Tokens rec'd
|
|
148
|
+
elif tx.from_address == event.address and TreasuryWallet.check_membership(
|
|
149
|
+
tx.to_address.address, tx.block # type: ignore [union-attr, arg-type]
|
|
150
|
+
):
|
|
151
|
+
tx_amount = round(tx.amount, 7)
|
|
152
|
+
try:
|
|
153
|
+
for i, amount in enumerate(event["token_amounts"]):
|
|
154
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
155
|
+
event_amount = round(tx.token.scale_value(amount), 7)
|
|
156
|
+
if tx_amount == event_amount:
|
|
157
|
+
pool = await Contract.coroutine(event.address) # type: ignore [assignment]
|
|
158
|
+
if hasattr(pool, "underlying_coins"):
|
|
159
|
+
coin: ChecksumAddress = await pool.underlying_coins.coroutine(i)
|
|
160
|
+
return tx.token == coin
|
|
161
|
+
else:
|
|
162
|
+
return tx.token == await _get_coin_at_index(pool, i)
|
|
163
|
+
else:
|
|
164
|
+
print(
|
|
165
|
+
f"Curve withdrawal multi amount does not match: {tx_amount} {event_amount}"
|
|
166
|
+
)
|
|
167
|
+
except EventLookupError:
|
|
168
|
+
# some other event has different keys, maybe we need to implement logic to capture these. time will tell.
|
|
169
|
+
pass
|
|
170
|
+
return False
|
|
Binary file
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ignore rules for Gearbox protocol transactions.
|
|
3
|
+
|
|
4
|
+
This module defines matching logic for Gearbox protocol deposit and
|
|
5
|
+
withdrawal swaps, so these transactions can be filtered from analytics
|
|
6
|
+
and reporting.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from dao_treasury import TreasuryTx
|
|
10
|
+
from y import Network
|
|
11
|
+
|
|
12
|
+
from yearn_treasury.rules.ignore.swaps import swaps
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
gearbox = swaps("Gearbox")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@gearbox("Deposit", Network.Mainnet)
|
|
19
|
+
def is_gearbox_deposit(tx: TreasuryTx) -> bool:
|
|
20
|
+
txhash = tx.hash
|
|
21
|
+
log_index = tx.log_index
|
|
22
|
+
return (
|
|
23
|
+
txhash == "0x5666b03add778468482fb376e65761128f9f5051b487f3efc996a55c3620d6d4"
|
|
24
|
+
and log_index in (366, 367)
|
|
25
|
+
) or (
|
|
26
|
+
txhash == "0x9e113dda11fcd758df2fe94a641aa7afe6329afec4097a8cb5d6fb68489cf7d8"
|
|
27
|
+
and log_index in (74, 75)
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@gearbox("Withdrawal", Network.Mainnet)
|
|
32
|
+
def is_gearbox_withdrawal(tx: TreasuryTx) -> bool:
|
|
33
|
+
txhash = tx.hash
|
|
34
|
+
return txhash == "0xb98d8f4dd3d9de50e6fec700fb8e5a732e5a564b7edfe365f97e601694536bb5" or (
|
|
35
|
+
txhash == "0x1d9e7930d0bf6725a4ffff43e284dfa9d10e34e16460e75d01a7f05a98e252a6"
|
|
36
|
+
and tx.log_index in (212, 213)
|
|
37
|
+
)
|
|
Binary file
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# mypy: disable-error-code=dict-item
|
|
2
|
+
from typing import Dict, Final, cast
|
|
3
|
+
|
|
4
|
+
from dao_treasury import TreasuryTx
|
|
5
|
+
from eth_typing import ChecksumAddress
|
|
6
|
+
from y import Contract, Network
|
|
7
|
+
|
|
8
|
+
from yearn_treasury.constants import ZERO_ADDRESS
|
|
9
|
+
from yearn_treasury.rules.ignore.swaps import swaps
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
IEARN: Final[Dict[str, ChecksumAddress]] = {
|
|
13
|
+
# v1 - deprecated
|
|
14
|
+
# v2
|
|
15
|
+
"yDAIv2": "0x16de59092dAE5CcF4A1E6439D611fd0653f0Bd01",
|
|
16
|
+
"yUSDCv2": "0xd6aD7a6750A7593E092a9B218d66C0A814a3436e",
|
|
17
|
+
"yUSDTv2": "0x83f798e925BcD4017Eb265844FDDAbb448f1707D",
|
|
18
|
+
"ysUSDv2": "0xF61718057901F84C4eEC4339EF8f0D86D2B45600",
|
|
19
|
+
"yTUSDv2": "0x73a052500105205d34daf004eab301916da8190f",
|
|
20
|
+
"yWBTCv2": "0x04Aa51bbcB46541455cCF1B8bef2ebc5d3787EC9",
|
|
21
|
+
# v3
|
|
22
|
+
"yDAIv3": "0xC2cB1040220768554cf699b0d863A3cd4324ce32",
|
|
23
|
+
"yUSDCv3": "0x26EA744E5B887E5205727f55dFBE8685e3b21951",
|
|
24
|
+
"yUSDTv3": "0xE6354ed5bC4b393a5Aad09f21c46E101e692d447",
|
|
25
|
+
"yBUSDv3": "0x04bC0Ab673d88aE9dbC9DA2380cB6B79C4BCa9aE",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
POOLS: Final = set(IEARN.values())
|
|
29
|
+
|
|
30
|
+
POOL_TO_UNDERLYING: Final[Dict[ChecksumAddress, ChecksumAddress]] = {
|
|
31
|
+
pool: ChecksumAddress(Contract(pool).token()) for pool in POOLS
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@swaps("iEarn:Withdrawal", Network.Mainnet)
|
|
36
|
+
def is_iearn_withdrawal(tx: TreasuryTx) -> bool:
|
|
37
|
+
# Vault side
|
|
38
|
+
if tx.to_address == ZERO_ADDRESS:
|
|
39
|
+
return tx.token_address in POOLS
|
|
40
|
+
# Token side
|
|
41
|
+
from_address = cast(ChecksumAddress, tx.from_address.address)
|
|
42
|
+
token_address = tx.token_address
|
|
43
|
+
return POOL_TO_UNDERLYING.get(from_address) == token_address
|
|
Binary file
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from typing import Final
|
|
2
|
+
|
|
3
|
+
from dao_treasury import TreasuryTx
|
|
4
|
+
from y import Network
|
|
5
|
+
|
|
6
|
+
from yearn_treasury.constants import CHAINID
|
|
7
|
+
from yearn_treasury.rules.ignore.swaps import swaps
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@swaps("OTC")
|
|
11
|
+
def is_otc_swap(tx: TreasuryTx) -> bool:
|
|
12
|
+
txhash = tx.hash
|
|
13
|
+
log_index = tx.log_index
|
|
14
|
+
for otc_swap in _OTC_SWAPS:
|
|
15
|
+
if isinstance(otc_swap, tuple):
|
|
16
|
+
if txhash == otc_swap[0] and log_index in otc_swap[1]:
|
|
17
|
+
return True
|
|
18
|
+
else:
|
|
19
|
+
if txhash == otc_swap:
|
|
20
|
+
return True
|
|
21
|
+
return False
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
_OTC_SWAPS: Final = {
|
|
25
|
+
Network.Mainnet: (
|
|
26
|
+
"0xd59dfba383c0a7d5f0e30124888fa6d9c2c964755fb9bed8f22483feb292c1e9",
|
|
27
|
+
"0xa00430b408c75dc432fcc0bbcabc5c3c63196addab532eecd233f6e80b295990",
|
|
28
|
+
"0x3419d8378321b5cb59c69584693ef59a65aeee4591e7e96c31f31906bc9a627a",
|
|
29
|
+
"0x30afed767aafd21696242c6a54576afc6598e976b969ffe50591360c729ef35a",
|
|
30
|
+
# Emergency dump of yvUSDN
|
|
31
|
+
"0xb22e345f58d7fe40257e41bac5d59ca74af8f6cc1e220aedf6f97113e4ace53a",
|
|
32
|
+
"0xd6bcaf0f144201d5c6affd73746ae57a262dbf00b957534a7b22bc0473bd589b",
|
|
33
|
+
# deprecated vault tokens
|
|
34
|
+
"0xf60060f25ae9f7d377741cde14d374a665dc8f1bff44f6fb231a1d89ac403711",
|
|
35
|
+
# ~8900 USDC sent back
|
|
36
|
+
"0xce4a854560f5b8f5d1790b7828ce90147eafee2f75cfc4009581977eebff8d51",
|
|
37
|
+
# "I moved them I moved them from yTrades to my EOA to dump since the liquidity was insanely small for OGV (mega price impact on cowswap) and there wasn't enough of VEC to justify cowswap"
|
|
38
|
+
# "I sold them to eth over time in my deployer EOA and am just gonna use it for gas"
|
|
39
|
+
"0x4713d14c624e0d4489980c91d3dc19fe468a9f0ad9c9b90fe4b7e55d9e67034e",
|
|
40
|
+
# vault tokens sent to swapper msig
|
|
41
|
+
(
|
|
42
|
+
"0xae7d281b8a093da60d39179452d230de2f1da4355df3aea629d969782708da5d",
|
|
43
|
+
(258, 262, 267, 272, 276),
|
|
44
|
+
),
|
|
45
|
+
# ~9136 crvUSD returned to treasury
|
|
46
|
+
"0xac1f2a5e2960577e54c4a9cd096763cb6df614aa28eff221aeb4159097d9fa0f",
|
|
47
|
+
# ~8112 USDC returned to treasury
|
|
48
|
+
"0x015cdac2a021a44404c56600a96acfe2cb768e8789031b150be51db18874ec77",
|
|
49
|
+
# one-off dumping 1INCH (on 1INCH not otc but this works)
|
|
50
|
+
"0x037477c516652437004050e955edb6bc0de82a6b0f03e7665009e802c196516f",
|
|
51
|
+
# not otc swap, but swapped by 0x444 so close enough
|
|
52
|
+
("0xd7e7abe600aad4a3181a3a410bef2539389579d2ed28f3e75dbbf3a7d8613688", (558, 559)),
|
|
53
|
+
"0x5a65d5299864ae6db364ee6a459a4f50d19e6fa8892f4f4c0221372b6c9b3ca2",
|
|
54
|
+
"0x71bd987e89940185b1131a6b73b981f5716c767ac12d106bf226a1aa8880f7c8",
|
|
55
|
+
),
|
|
56
|
+
}.get(
|
|
57
|
+
CHAINID, ()
|
|
58
|
+
) # type: ignore [call-overload]
|
|
Binary file
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ignore rules for PoolTogether protocol transactions.
|
|
3
|
+
|
|
4
|
+
This module defines matching logic for PoolTogether deposits swaps,
|
|
5
|
+
as they can be safely ignored in analytics and reporting.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dao_treasury import TreasuryTx
|
|
9
|
+
from y import Network
|
|
10
|
+
|
|
11
|
+
from yearn_treasury.constants import ZERO_ADDRESS
|
|
12
|
+
from yearn_treasury.rules.ignore.swaps import swaps
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@swaps("PoolTogether:Deposit", Network.Mainnet)
|
|
16
|
+
def is_pooltogether_deposit(tx: TreasuryTx) -> bool:
|
|
17
|
+
# TODO: figure out what was done with the withdrawals and put a note here
|
|
18
|
+
symbol = tx.symbol
|
|
19
|
+
return (
|
|
20
|
+
symbol == "POOL" and tx.to_address.address == "0x396b4489da692788e327E2e4b2B0459A5Ef26791"
|
|
21
|
+
) or ( # type: ignore [union-attr]
|
|
22
|
+
symbol == "PPOOL" and tx.from_address.address == ZERO_ADDRESS
|
|
23
|
+
) # type: ignore [union-attr]
|
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from dao_treasury import TreasuryTx
|
|
2
|
+
from y import Network
|
|
3
|
+
|
|
4
|
+
from yearn_treasury.rules.ignore.swaps import swaps
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@swaps("Synthetix", Network.Mainnet)
|
|
8
|
+
def is_synthetix_swap(tx: TreasuryTx) -> bool:
|
|
9
|
+
# TODO Figure out hueristics for sorting these if they become more frequent
|
|
10
|
+
return tx.hash == "0x5a55121911d9a3992fc1ea9504da9b86331da2148822d88c16f805b2c6b2c753"
|
|
@@ -57,7 +57,7 @@ async def is_uniswap_deposit(tx: TreasuryTx) -> bool:
|
|
|
57
57
|
if any(
|
|
58
58
|
tokens[1] == transfer.address
|
|
59
59
|
and tx.to_address
|
|
60
|
-
== transfer.values()[:1]
|
|
60
|
+
== transfer.values()[:1] # type: ignore [index]
|
|
61
61
|
== [mint["sender"], mint.address]
|
|
62
62
|
for transfer in transfers
|
|
63
63
|
):
|
|
@@ -78,7 +78,7 @@ async def is_uniswap_deposit(tx: TreasuryTx) -> bool:
|
|
|
78
78
|
if any(
|
|
79
79
|
tokens[0] == transfer.address
|
|
80
80
|
and tx.to_address
|
|
81
|
-
== transfer.values()[:1]
|
|
81
|
+
== transfer.values()[:1] # type: ignore [index]
|
|
82
82
|
== [mint["sender"], mint.address]
|
|
83
83
|
for transfer in transfers
|
|
84
84
|
):
|
|
@@ -190,6 +190,9 @@ async def is_uniswap_withdrawal(tx: TreasuryTx) -> bool:
|
|
|
190
190
|
return CHAINID == Network.Mainnet and tx.hash in (
|
|
191
191
|
"0xf0723677162cdf8105c0f752a8c03c53803cb9dd9a6649f3b9bc5d26822d531f",
|
|
192
192
|
"0xaf1b7f138fb8bf3f5e13a680cb4a9b7983ec71a75836111c03dee6ae530db176", # v3
|
|
193
|
+
# these use ETH not WETH so they dont match
|
|
194
|
+
"0x5b05dfd3305c471df0ad944237edc2dbb14b268f7415252de566a5ab283002af",
|
|
195
|
+
"0x46ab9b383751f612ea0de8c0c6e9fa86e7324de04b032ecb48161989b7dbdbf7",
|
|
193
196
|
)
|
|
194
197
|
|
|
195
198
|
|
|
@@ -240,11 +243,21 @@ async def is_uniswap_swap(tx: TreasuryTx) -> bool:
|
|
|
240
243
|
continue
|
|
241
244
|
|
|
242
245
|
if tx.token == token0:
|
|
243
|
-
|
|
246
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
247
|
+
event_amount = round(tx.token.scale_value(swap["amount0In"]), 10)
|
|
248
|
+
if event_amount == round(tx.amount, 10):
|
|
244
249
|
return True
|
|
250
|
+
print(
|
|
251
|
+
f"Uniswap sell token0 amount does not match: {round(tx.amount, 10)} {event_amount}"
|
|
252
|
+
)
|
|
245
253
|
elif tx.token == token1:
|
|
246
|
-
|
|
254
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
255
|
+
event_amount = round(tx.token.scale_value(swap["amount1In"]), 10)
|
|
256
|
+
if event_amount == round(tx.amount, 10):
|
|
247
257
|
return True
|
|
258
|
+
print(
|
|
259
|
+
f"Uniswap sell token1 amount does not match: {round(tx.amount, 10)} {event_amount}"
|
|
260
|
+
)
|
|
248
261
|
|
|
249
262
|
# Buy side
|
|
250
263
|
elif tx.from_address == swap.address and TreasuryWallet._get_instance(
|
|
@@ -259,11 +272,21 @@ async def is_uniswap_swap(tx: TreasuryTx) -> bool:
|
|
|
259
272
|
# This will be recorded elsewhere
|
|
260
273
|
continue
|
|
261
274
|
if "amount0Out" in swap and tx.token == token0:
|
|
262
|
-
|
|
275
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
276
|
+
event_amount = round(tx.token.scale_value(swap["amount0Out"]), 9)
|
|
277
|
+
if event_amount == round(tx.amount, 9):
|
|
263
278
|
return True
|
|
279
|
+
print(
|
|
280
|
+
f"Uniswap buy token0 amount does not match: {round(tx.amount, 9)} {event_amount}"
|
|
281
|
+
)
|
|
264
282
|
elif "amount1Out" in swap and tx.token == token1:
|
|
265
|
-
|
|
283
|
+
# TODO: get rid of this rounding when we migrate to postgres
|
|
284
|
+
event_amount = round(tx.token.scale_value(swap["amount1Out"]), 10)
|
|
285
|
+
if event_amount == round(tx.amount, 10):
|
|
266
286
|
return True
|
|
287
|
+
print(
|
|
288
|
+
f"Uniswap buy token1 amount does not match: {round(tx.amount, 10)} {event_amount}"
|
|
289
|
+
)
|
|
267
290
|
return False
|
|
268
291
|
|
|
269
292
|
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ignore rules for the Unwrapper contract.
|
|
3
|
+
|
|
4
|
+
This module defines matching logic for swaps involving the Unwrapper
|
|
5
|
+
contract, so those transactions can be ignored from analytics and
|
|
6
|
+
reporting.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from dao_treasury import TreasuryTx
|
|
10
|
+
from y import Network
|
|
11
|
+
|
|
12
|
+
from yearn_treasury.rules.ignore.swaps import swaps
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@swaps("Unwrapper", Network.Mainnet)
|
|
16
|
+
def is_unwrapper(tx: TreasuryTx) -> bool:
|
|
17
|
+
return "Contract: Unwrapper" in [tx.from_nickname, tx.to_nickname]
|
|
Binary file
|