eth-portfolio 0.5.7__cp312-cp312-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 eth-portfolio might be problematic. Click here for more details.

Files changed (83) hide show
  1. eth_portfolio/__init__.py +24 -0
  2. eth_portfolio/_argspec.cp312-win32.pyd +0 -0
  3. eth_portfolio/_argspec.py +43 -0
  4. eth_portfolio/_cache.py +119 -0
  5. eth_portfolio/_config.cp312-win32.pyd +0 -0
  6. eth_portfolio/_config.py +4 -0
  7. eth_portfolio/_db/__init__.py +0 -0
  8. eth_portfolio/_db/decorators.py +147 -0
  9. eth_portfolio/_db/entities.py +311 -0
  10. eth_portfolio/_db/utils.py +616 -0
  11. eth_portfolio/_decimal.py +154 -0
  12. eth_portfolio/_decorators.py +84 -0
  13. eth_portfolio/_exceptions.py +65 -0
  14. eth_portfolio/_ledgers/__init__.py +0 -0
  15. eth_portfolio/_ledgers/address.py +924 -0
  16. eth_portfolio/_ledgers/portfolio.py +328 -0
  17. eth_portfolio/_loaders/__init__.py +33 -0
  18. eth_portfolio/_loaders/_nonce.cp312-win32.pyd +0 -0
  19. eth_portfolio/_loaders/_nonce.py +193 -0
  20. eth_portfolio/_loaders/balances.cp312-win32.pyd +0 -0
  21. eth_portfolio/_loaders/balances.py +95 -0
  22. eth_portfolio/_loaders/token_transfer.py +215 -0
  23. eth_portfolio/_loaders/transaction.py +240 -0
  24. eth_portfolio/_loaders/utils.cp312-win32.pyd +0 -0
  25. eth_portfolio/_loaders/utils.py +67 -0
  26. eth_portfolio/_shitcoins.cp312-win32.pyd +0 -0
  27. eth_portfolio/_shitcoins.py +342 -0
  28. eth_portfolio/_stableish.cp312-win32.pyd +0 -0
  29. eth_portfolio/_stableish.py +42 -0
  30. eth_portfolio/_submodules.py +72 -0
  31. eth_portfolio/_utils.py +215 -0
  32. eth_portfolio/_ydb/__init__.py +0 -0
  33. eth_portfolio/_ydb/token_transfers.py +145 -0
  34. eth_portfolio/address.py +396 -0
  35. eth_portfolio/buckets.py +212 -0
  36. eth_portfolio/constants.cp312-win32.pyd +0 -0
  37. eth_portfolio/constants.py +87 -0
  38. eth_portfolio/portfolio.py +662 -0
  39. eth_portfolio/protocols/__init__.py +64 -0
  40. eth_portfolio/protocols/_base.py +107 -0
  41. eth_portfolio/protocols/convex.py +17 -0
  42. eth_portfolio/protocols/dsr.py +50 -0
  43. eth_portfolio/protocols/lending/README.md +6 -0
  44. eth_portfolio/protocols/lending/__init__.py +50 -0
  45. eth_portfolio/protocols/lending/_base.py +56 -0
  46. eth_portfolio/protocols/lending/compound.py +186 -0
  47. eth_portfolio/protocols/lending/liquity.py +108 -0
  48. eth_portfolio/protocols/lending/maker.py +110 -0
  49. eth_portfolio/protocols/lending/unit.py +44 -0
  50. eth_portfolio/protocols/liquity.py +17 -0
  51. eth_portfolio/py.typed +0 -0
  52. eth_portfolio/structs/__init__.py +43 -0
  53. eth_portfolio/structs/modified.py +69 -0
  54. eth_portfolio/structs/structs.py +626 -0
  55. eth_portfolio/typing/__init__.py +1418 -0
  56. eth_portfolio/typing/balance/single.py +176 -0
  57. eth_portfolio-0.5.7.dist-info/METADATA +26 -0
  58. eth_portfolio-0.5.7.dist-info/RECORD +83 -0
  59. eth_portfolio-0.5.7.dist-info/WHEEL +5 -0
  60. eth_portfolio-0.5.7.dist-info/entry_points.txt +2 -0
  61. eth_portfolio-0.5.7.dist-info/top_level.txt +3 -0
  62. eth_portfolio__mypyc.cp312-win32.pyd +0 -0
  63. eth_portfolio_scripts/__init__.py +17 -0
  64. eth_portfolio_scripts/_args.py +26 -0
  65. eth_portfolio_scripts/_logging.py +14 -0
  66. eth_portfolio_scripts/_portfolio.py +209 -0
  67. eth_portfolio_scripts/_utils.py +106 -0
  68. eth_portfolio_scripts/balances.cp312-win32.pyd +0 -0
  69. eth_portfolio_scripts/balances.py +56 -0
  70. eth_portfolio_scripts/docker/.grafana/dashboards/Portfolio/Balances.json +1962 -0
  71. eth_portfolio_scripts/docker/.grafana/dashboards/dashboards.yaml +10 -0
  72. eth_portfolio_scripts/docker/.grafana/datasources/datasources.yml +11 -0
  73. eth_portfolio_scripts/docker/__init__.cp312-win32.pyd +0 -0
  74. eth_portfolio_scripts/docker/__init__.py +16 -0
  75. eth_portfolio_scripts/docker/check.cp312-win32.pyd +0 -0
  76. eth_portfolio_scripts/docker/check.py +66 -0
  77. eth_portfolio_scripts/docker/docker-compose.yaml +61 -0
  78. eth_portfolio_scripts/docker/docker_compose.cp312-win32.pyd +0 -0
  79. eth_portfolio_scripts/docker/docker_compose.py +97 -0
  80. eth_portfolio_scripts/main.py +118 -0
  81. eth_portfolio_scripts/py.typed +1 -0
  82. eth_portfolio_scripts/victoria/__init__.py +72 -0
  83. eth_portfolio_scripts/victoria/types.py +38 -0
@@ -0,0 +1,342 @@
1
+ from collections import defaultdict
2
+ from typing import DefaultDict, Final
3
+
4
+ from eth_typing import ChecksumAddress
5
+ from y import Network, convert
6
+
7
+ shitcoins: Final = {
8
+ Network.Mainnet: [
9
+ # Tagged as fake on Etherscan
10
+ "0xb8ac53AFCCEBc44AaC33D0C30E2Ae0783E7fde5f",
11
+ "0xe397ef3E332256F38983ffaE987158da3e18c5Ec",
12
+ "0x7452E3fC2fE611C6B7761c6c393BECe059881aC7",
13
+ "0x4ab16CDc82a4eA4727Ab40caee1bb46622C13641",
14
+ "0x471c3A7f132bc94938516CB2Bf6f02C7521D2797",
15
+ "0x106EebF11F34ECCcaD59c1CA9398d828765f64f8",
16
+ "0x634a31d5DB29F2a646bADAd27bb7b1E5A78FD316",
17
+ "0xF673623e8507551BDe72290E909c7E184A4799a3",
18
+ "0x269641A320F8465eF4e710F51Dc6e6862D7E8A77",
19
+ "0x956F824B5a37673c6fC4a6904186cB3BA499349B",
20
+ "0xBFA9180729f1c549334080005Ca37093593fB7Aa",
21
+ "0x643695D282f6BA237afe27FFE0Acd89a86b50d3e",
22
+ # Tagged as spam on Etherscan
23
+ "0x3B809ABd5a7597F8d1cf7dEB2747A1e1580C1488",
24
+ "0xCfB0Ef3e179427316FBD7F0D0296F173762BeEE0",
25
+ "0xfAFe8a7c0A9b3807CC1df0DEB0BA0B5a5fb7A872",
26
+ "0xdf66B9727553fB9Bfa417699CB8F60425d62d1E3",
27
+ "0x68Ca006dB91312Cd60a2238Ce775bE5F9f738bBa",
28
+ "0xBCCBeDAb3Bf6FA1cfC3e2d07Aa5ce4A282864D6E",
29
+ "0x26004d228fC8A32c5bd1a106108c8647A455B04a",
30
+ "0x635701CC5fE41FE8AbD02aa74Beb02e3540E9BB2",
31
+ "0xf8358bd95dcA48187e3F4BE05847F3593776C086",
32
+ "0x459176FDC68C945B6bb23eB946eee62457041567",
33
+ "0xf55F8aA8F3d777f1aB3A4ae9E269C8D7B73078De",
34
+ "0x434d5875534D19fC7105281Cf61dbfd1C93c8cb1",
35
+ "0x908599FDf490b73D171B57731bd4Ca95b7F0DE6a",
36
+ "0x4709099BE25D156578405132d66aeBfC2e12937A",
37
+ "0x82315517d61ecf47f9A78705127934F3d431cB21",
38
+ "0x2B000332CD291eF558aF76298A4d6F6001E4e015",
39
+ "0x163F4D81d86ac282A0F0F94D9FE3E0321ACcfd37",
40
+ "0x660235331d2FA5FeB7a49F31556B0Be31f02560D",
41
+ "0x696F33F4dd9BE5538483f63308453D2D67D07331",
42
+ "0xcbbadd74b3bb09836d97d91050e13E06089ba485",
43
+ "0xE0c31b3e341E7EF3C04eB14E58802b88a80A45A1",
44
+ "0xA6D74802a2222d5cCe5eA0531159ed878943b54c",
45
+ "0xcAB80A2bf07BECaF8d48168081352ea873B8Db91",
46
+ "0x72B12aec69dA93357f2B69aCf33d5B75cF17575B",
47
+ "0xA4C8A13FeE3b19718E45d678C071bDE3e33A7302",
48
+ "0x579e4ca5888eD1420492988BF75E26D9e7B4C535",
49
+ "0xB80216D5b4eec2BEc74eF10e5d3814Fec6Fd8af0",
50
+ "0x6A007E207E50B4C6B2ADCFc6a873F6e698645fE3",
51
+ "0x84d12988D71244a8937a9816037BeB3e61E17FdD",
52
+ "0x0734E85525Ca6838fe48EC6EB29b9d457F254F73",
53
+ "0xa10c97bF5629340A35c41a8AA308af0804750605",
54
+ "0x69D732F50e248D4B825d524fEDEB0D7Ce3d76352",
55
+ "0xAF0b2fBeDd5d1Fda457580FB3DAbAD1F5C8bBC36",
56
+ "0xbadb4170Cd3309680477Fc81D527101cbB4000EE",
57
+ "0x7841479c5976b8184DBcde9a7a5113901b233EfB",
58
+ "0x1e4A0ADFC2e9bf2Dfd041Bc89405538d0D5A077a",
59
+ "0xb07de4b2989E180F8907B8C7e617637C26cE2776",
60
+ "0xa9517B2E61a57350D6555665292dBC632C76adFe",
61
+ "0x38715Ab4b9d4e00890773D7338d94778b0dFc0a8",
62
+ "0x6171136E82a2f1bAA2494c69528f599467EfeA20",
63
+ "0x9Ee582c42F88CAA5e7BCDE2e86e69Af3Cf5FCe40",
64
+ "0xFD1860C9d602236214652a21753731F9acD2C362",
65
+ "0x0Fd23DaB8723b1Fd5e7c3d74Baa624B443423b6B",
66
+ "0xe0736F3F455F1DBD29Bf6F8346EAd22f5CF78d08",
67
+ "0x7F57A01fc540ca3A26345C4903B9a220aD048196",
68
+ "0x635701CC5fE41FE8AbD02aa74Beb02e3540E9BB2",
69
+ "0xF709642622729feafC8bf0934679706df49d8A30",
70
+ # Tagged as phishing on Etherscan
71
+ "0x4AeDC0B9Acdf5BE1d312Ace7c2df425C2f56F9C3",
72
+ "0xd16A07Ac860c95F3E225b3A847F81C267b3f929d",
73
+ "0x211c1eB92D74cbdA58bA82116502fD02dd8F319E",
74
+ "0x6ef7D6682086Ad4936D2bC141cD94b2c43476FeD",
75
+ "0x0C98216a20f8e19C1483cf8B307A5E9ce758428D",
76
+ "0x6426b6C2A9108Fa815bcccA3a3232301E1895742",
77
+ "0x0bF377fb3b5F1dD601e693B8fAF6b0bD249f37D3",
78
+ "0xBf5fB1563ef58ba41325454ca61Cc3D62bd40744",
79
+ "0x54fd62228C6e1234fd5Fded28555CA963Dcf6d26",
80
+ "0xA36Ceec605d81aE74268Fda28A5c0Bd10b1D1f7C",
81
+ "0xF9d25EB4C75ed744596392cf89074aFaA43614a8",
82
+ "0x1412ECa9dc7daEf60451e3155bB8Dbf9DA349933",
83
+ "0x1fc4DB3e7f9124bAAFB7B34346dB7931Dad621C2",
84
+ "0x120aA018634F555484c088c8da80F75Aa07E004F",
85
+ "0xeDe11D3d5dd7D5454844f6f121cc106bF1144a45",
86
+ "0x875bf9be244970B8572DD042053508bF758371Ee",
87
+ "0x070C0147884D7CF984aFBC2Eb6F3428A39b5E229",
88
+ "0xb0B1d4732eFE32AEA466ED6BC3c79181eD4810c4",
89
+ "0xCf39B7793512F03f2893C16459fd72E65D2Ed00c",
90
+ "0x89532890c2959e836C1Bca52309356841238b8B7",
91
+ "0xD1B0c350f73E6f7Cd5c9978b82B46a59aE9aD524",
92
+ "0x17a10104CBC1eD155D083eaD9FCF5C3440bb50e8",
93
+ "0x8eB3FecAAA963C86d9b49004d9f28092f1Db3D6c",
94
+ "0x52bbca3B24c1c1ac050fF4546F37AA88282aaE22",
95
+ "0xECF0dE4C8498Cfd686E4702D955426b22d812d6B",
96
+ "0xF01f7A348681776c1FC9A066c6973882B693cdC6",
97
+ "0x0e1CD6d2715432e4DBedFE969b0Eb2867FF61d5b",
98
+ "0x9aE357521153FB07bE6F5792CE7a49752638fbb7",
99
+ # Generally looks like shit
100
+ "0x322Ec1ed696575670D66649Ea1284ff243fE4A1e",
101
+ "0x9DeB0fc809955b79c85e82918E8586d3b7d2695a",
102
+ "0x2fFBB3549D034b5e5879670f4af58727CDc72946",
103
+ "0xc39B6cf191f402697ba2F3Bedf5faA9837038d42",
104
+ "0x5e43e50A3cB43Fb71eD2500bC847E8d25b8335f9",
105
+ "0xE8ED1fca5af1c7dd46A3D5bbDFf7e99749D9e0aa",
106
+ "0x00d0F0250364C431376cC64AADd3aa13c6A8998D",
107
+ "0x256099A072ea5fd35eC134758440413095967109",
108
+ "0xe975ACEb3b61a88A355B066D9cCC910CAb8b4853",
109
+ "0x59fF00f75b49089385377c7f7D905E193c9eb5e2",
110
+ "0x99304A346F8FD562336Fd3485301c02cEbE4F0ae",
111
+ "0x74b1C36268B5dC659aEEA588cb1683E96DaaB71a",
112
+ "0x92BF340B2c67be6911095675f744F9a3aD22d8F0",
113
+ "0xa635305B4a6A1E4A55Eb6A6B54a8D2a55e914F6f",
114
+ "0xC76f77Bff99Ec269050Ca929F4d37B00f012c65F",
115
+ "0x56BcBef8f5Ca4Fc224fE58187c66EA34d3A1ef4a",
116
+ "0xdc6050Ec75Bc4692333A1C301eB799e348d0b77e",
117
+ "0x0542e502cec25bD51b4f3461f4F704807FA1A6D8",
118
+ "0xc01e807Cc73469e9983B614A96847BC01332447d",
119
+ "0x87D38d662A4aae29BB60057e71AFf923C7523DC3",
120
+ "0xDFC01a7956C0d151ae197274B974fA7527EbAFB9",
121
+ "0xE256CF1C7caEff4383DabafEe6Dd53910F97213D",
122
+ "0x7CD6143B8781dC7e0667e50DB02Eb6539799722F",
123
+ "0x174Cd3359C6a4E6B64D2995Da4E2E4631379526E",
124
+ "0x85E199607eb8aEef775Ae6424b42d20616267852",
125
+ "0x4D57c67C8Bab0Fb3A0a0A35B904FBff4E5450521",
126
+ "0x884a886D17a64852d18e5921fA7A05ae2954C9Bb",
127
+ "0xbB5c3B198f6def369bFB6AC7A34BB08eA49a0770",
128
+ "0x5be480Aa056ec274e5aE970d7A75dF0c9620F6F8",
129
+ "0xA1f76F1c94078f7d2E05152DC3e31dED819dfDC0",
130
+ "0xCE3F076D0ADa9f913a24F42dEAB82e4b851B87d6",
131
+ "0xB215F3927192181eBCD79227c70c10015Ff10df3",
132
+ "0x37843BC944eDBb0477df943d9061D359004a4e70",
133
+ "0x9A7ddeE20b61EA4f4812665EdF39dD157a66E873",
134
+ "0xfcBe0B695c13257bd43D64f09Db433034E90033D",
135
+ "0x7d09A736c5FB1Db357dE04A07DEB22D5829DA26F",
136
+ "0x6Ac9cA5710Ba6B985b46fd5282a59eBbea3434d4",
137
+ "0xD6619A3E925472a8d7822Cc6A49B76b3554A3498",
138
+ "0x338C1E2B51C4E818765a887584e7041EF9070aef",
139
+ "0x83D473D1acD97Aa45A97c3b778fB5714e7e4c604",
140
+ "0x5bb38F4899797f03141782E9d2130C12769c0CCc",
141
+ "0x1F7B20004eBd7E258b9f45568cE789fC5d2140fb",
142
+ "0x92Aeed8027735C41605577b45A69429Bd7f729f9",
143
+ "0x8A801C334ebaC763822a0D85a595AeC6Da59C232",
144
+ "0xd5b0Bd07864C0aaCC3b6Cd5e63C68c62C0F263d2",
145
+ "0x2b23BF339F5cc3393a558373E0A73a576F0838D3",
146
+ "0x7B2e238FB48ee7322664B9C26bb3ACedBfCC1f70",
147
+ "0x08918171758171A13050cdE6Cc6eB90172Af5737",
148
+ "0x9398c448728738039b91687919262194899D3f27",
149
+ "0x0A527683c3154F5F9E1b4203Ef4d05962b2411bf",
150
+ "0xe3C6F9D0d731C2Eb6B6D3eBFb6732fCd26a365d0",
151
+ "0x6cF0B5A20B2d4b55e6b752d7016275B892035652",
152
+ "0x98d1c76831c0aBEa30e3dac8628BD72d6B0E3dd2",
153
+ "0x4C6fDc0476B2FE0daFf0B5824c3A918673d6014E",
154
+ "0xC6d3D201530a6D4aD9dFbAAd39C5f68A9A470a69",
155
+ "0x525fC44CBE181C1108c209091B5EEc5a5028190d",
156
+ "0x7d1a6a4f806A4a64AD32e7F2350E176eA6B9a1F6",
157
+ "0x75E34A4A04d5f5F7Fc01801d2d287d64D882529B",
158
+ "0x8F49cB69ee13974D6396FC26B0c0D78044FCb3A7",
159
+ "0xB688d06d858E092EBB145394a1BA08C7a10E1F56",
160
+ "0x154C5875b1B0DB1794f88D003730DaD160E6b38e",
161
+ "0x11068577AE36897fFaB0024F010247B9129459E6",
162
+ "0xBA89375bAE9b3DE92442e9C037d4303A6e4FB086",
163
+ "0xcDbd4089C2F98DA715e52127680f87aFdB183A2e",
164
+ "0x3a3a4d2d9755283D9e25105B042C5f45BC0Edf05",
165
+ "0x70c18F2fDcb00d27494f767503874788e35c9940",
166
+ "0xF511123fdf2F13811abf4edDb493860101471729",
167
+ "0x830Cbe766EE470B67F77ea62a56246863F75f376",
168
+ "0x76988Eb5d8a81F44919d87328c36179FdCca044a",
169
+ "0xa6DE609807c7258A0D34F5307c1808F062A59794",
170
+ "0x698068C6a369b1BF04D516f5fE48424797973DCf",
171
+ "0xbEb3c5F7f4F8dB708BcfaC4D0fDcDb0bEd285741",
172
+ "0xCdC94877E4164D2e915fC5E8310155D661A995F1",
173
+ "0x5D80A8D8CB80696073e82407968600A37e1dd780",
174
+ "0x19383F024BA4c06e44D11a8B8BB7ebF87faB184C",
175
+ "0xF5b2C59F6DB42FFCdFC1625999C81fDF17953384",
176
+ "0xdb83eC9EEAC2b3CF8Eb282f91c73C38159578697",
177
+ "0x2F30E0F6B484eF6Be57b6435e34687018ff8Cb4D",
178
+ "0x242a705E8AF8A24B7EB30f3DbAF899eB25E3D76A",
179
+ "0x2f848B4A2B5dfC3b9e4Eb229551c0887E6348653",
180
+ "0x0795619E02716a81ac9EF6E55363D538DA104e57",
181
+ "0x6D9541ba0f1039d0f8636b4f39D20A8a7464f357",
182
+ "0x1C3d9Db84e0EEE4744893A7FAeE6187F31E39539",
183
+ "0x3654746Ce159BA2FCDF926133D51ecBb85f19288",
184
+ "0x67542502245eb5DF64eF7Ea776199CeB79401058",
185
+ "0x0951490Cec0261F60Ff0C42DE7F62488Cc8313D8",
186
+ "0x154C5875b1B0DB1794f88D003730DaD160E6b38e",
187
+ "0xcdBb37f84bf94492b44e26d1F990285401e5423e",
188
+ "0x53d345839E7dF5a6c8Cf590C5c703AE255E44816",
189
+ "0xCCCCee7d9B0f18ab16b217A794D2671549F1A895",
190
+ "0xc6a76f7ad66d0e6Ccd1AaAd6e7568c9bd55Dce62",
191
+ "0xB4d4334eB5a251cbE5cC7Afb0Ba26119aCE62281",
192
+ "0xE5c5AE39B98eFd9D3c9E0F2a5457D98fFA4b0b46",
193
+ "0x912033c6644008DD8438A5C07738a513f38Ded5D",
194
+ "0xffE49E3BB3725d499223611e571215029877A6Cf",
195
+ "0x7d593cC8E0b8ceBF645342AaFf5631e689FB5249",
196
+ "0x3E67A4D218061263202c1480ddB479080C59dd0E",
197
+ "0xac4607A2D8a2bfA721955a23D3F290B0E176612E",
198
+ "0x27ed436e67515C1dD33633537EEBd59207c51806",
199
+ "0x92b48cf18a947c66557CE4aC829D6DB012D11Aa5",
200
+ "0x16D6FB8a5c736feB50579106a39F6e14798A3D22",
201
+ # Generally looks like shit (symbol ERC20)
202
+ "0x2adA6e459089292264133d8D7c85f6907423E444",
203
+ "0x356F680eE21c8CeFfA460c38D20A137F3D07D9af",
204
+ "0x683eAca6CD17383FA93e95f17e7DE443666160eB",
205
+ "0x7452cc6Bd1FA968dd1672FF447f3D7ff1ce210A8",
206
+ "0x773F67800a6d79C0198E8Ac798658f80cb346083",
207
+ "0xaE977D03F5A3999c762eb42a203c436dFF3Df03C",
208
+ "0xbD67D76edFD88719efD7669583258209015B0aB5",
209
+ "0xd814cd86ed2e85156d9Cf3A9319261259458f50c",
210
+ "0xd0E6420b900dE49113B3404b437ee153Bf220B36",
211
+ "0xf1D1C6ea9166bcF97A099A1388E1663933bB2E48",
212
+ "0xF8B49aEC3E356f911f86F58Ff9204242d4b0e6A5",
213
+ "0xe37be01D1337E77aCB0b4293DDb4D410D80010a7",
214
+ "0x7EeAcC32C81e4D78E9705fBf0b977f5A858Bf0F3",
215
+ "0x90133FF815ade1977EA2f1454dBC1d309EAA33f6",
216
+ "0x82ff6D346E424025B1F07e4C8D6527806e50fCA5",
217
+ "0x7C2bc9F685e1f78e42d236Ff819D89DDA864359d",
218
+ "0x3ea463dD031A384DB68d6fD2f37574248E7ffCfE",
219
+ "0x241b047e810c70AB2bB5C567391E0888c4791cbe",
220
+ "0x47D1b57e5B542808eeEd0C509583Fa12d023f05e",
221
+ "0x8a33B3e6f5C0049Cff6dEca0564F5fbDa0eBe9f9",
222
+ "0x84b2e82Ef534e8bE05276DBf4F9e5474fBeD5E59",
223
+ "0x022b5fE59fc45a29d58a7e45a2567b69b649d623",
224
+ "0x178d20220c22008cc1886d2E689cAeE4A5c3239b",
225
+ # Tagged as well known address scam on Etherscan
226
+ "0x59bed83a385571ffac0FC15A43f0f6f72e66Dccb",
227
+ "0x2Ec109a0ceFEC70661a242a8B54cae8f45630397",
228
+ "0x11d666B9C8fa057774324a9bFe6B53eB8d23079f",
229
+ "0x0598BEf845934d83463cEaDd8C86F0801e2Ee058",
230
+ "0xAcDfe439652F78750AFCe1BbA2cB9068EDb4e69c",
231
+ "0xd3cc310DD7b94D6Ef06615f73A3029A67d935c5E",
232
+ "0x0C6D7f5a8c122aCB941aCb95cb99C2cdE893b7a7",
233
+ "0xCBd85ffF5106a42d622be7F9e528DB0bfF07Da8A",
234
+ "0x22e810C6aed30FA93C2D2B62F456E5f78e8918e1",
235
+ "0xc750d0c91DD5f2D3964931FF5dC42B2bB3e008C1",
236
+ "0x6284C089D6944df1ba61bd56618AEba07D1d6136",
237
+ "0x4E654E3A532a386329bde5f01D0AC7995Ab94c07",
238
+ "0x570EC272F07c563860477DCAfB04a04FFd2979a1",
239
+ "0xEcd8eDb13Cd68707579D5EC891A24C03B8d5E831",
240
+ "0x5D6434D533922d60F1eeec913f680C5daF31cB9A",
241
+ "0x15B8adFa95e841a55867495F07B8102329546987",
242
+ "0xFe0bb2ae94BF11de9773DECb413b4a6a241cBCd0",
243
+ "0x4d3D07f4E7a154c32D36bBcBE2Ea64E0B6F98440",
244
+ "0xEea2fEf22353282fb760d27EA7A1E2f06B3F442d",
245
+ "0x218Ae209BEc57eeFa9149789aE09388459bC91d1",
246
+ "0x4639FFC90b0fD6Dffb57Af712109bfa419afaEB5",
247
+ "0x39dDC0a04F0E1F2830f3f1FEc414cD6E23168beE",
248
+ "0x4a41775Da459B38e641141e4C696DF10EC1f4983",
249
+ "0x72C07D9151DcE2ea862595487ef7e21cC312e564",
250
+ "0xE00cD9B8ebb503E4bE266983EfC6158fCFfe0004",
251
+ "0x46DDf95a62b0F2eF6dc4e70717f36172a595517F",
252
+ "0x7cfa05320D83A20980Ac76B91a3A11981877Ef3A",
253
+ "0xbbaC5B019876534c3C399F56E150684c5015F670",
254
+ "0x2840a9fC9ad15738c762e404300761eC828aFFCb",
255
+ "0xC1c8c49b0405f6CFfBA5351179bEFB2d8a2c776c",
256
+ "0xcB56B36Ef3d4E5C3b7d2fbC4f4Ee5d525893a555",
257
+ "0x5807daC5CC59F02dFA88154dE7F9f2174C263814",
258
+ "0x6545B409acdD7e1BE14C835B5c3B826C5d312D02",
259
+ "0xdF781bBA6F9EefB1A74bb39f6DF5e282c5976636",
260
+ "0x85D385244D41ac914484FD6fbBaB177c10A86e79",
261
+ "0xa51a8578052EdEB4Ced5333A5e058860d9E7a35b",
262
+ "0x7a6b87D7a874Fce4c2d923b09C0E09e4936bcF57",
263
+ "0xFabb91ae9318082505c2c6d7acD9d521d4eDDEFf",
264
+ "0x5807daC5CC59F02dFA88154dE7F9f2174C263814",
265
+ # fake USDC
266
+ "0x4Fe8CEdb3f76Ed69b4914958B80Cf9c6D4E3b416",
267
+ "0xa75Fa7DEa69aBd84C9812919039Cb33e2092aab6",
268
+ "0x37dC2fD3A38fd3E898299E754C19772A67f1912B",
269
+ "0x445A32D3095D1ea8951180B0fD6004258beB72F3",
270
+ "0xBD3E4E06074F6bBDfa8B24Ba0736db4DE77EAF0A",
271
+ "0xAba86342C3f57E002F47F6eb38099A577312F2e8",
272
+ "0x94C4bfDD351A2EeA9d57e602C2a24d6Fe823Fd1a",
273
+ "0xAfF006725DeeAF5BF6750A6C7c98D9e70cB189a4",
274
+ "0x54c4D37aD550f9776CE2021df245d98B4Bb5Cb5E",
275
+ # fake USDC
276
+ "0x98a7800EB17e1A0e2b2A4b69e83c58F4535F2180",
277
+ "0xdC5BCA9992191c900D7A7F5b8e1b3e4161d1aa51",
278
+ "0xd27255AA153ae470419B0198fa61e892a612aFE8",
279
+ "0xbADbe6619c0563c60E62C7409681440a80391a27",
280
+ "0x89D3Ac7C32Aa14bEE6Fa90E041241dc4eEbbDFB3",
281
+ "0x640c6fdAfbDaC9bfCe79943890fdc98f8d39bE3e",
282
+ "0xA04a3a553548090a7b81D2de75B8a08Ee45860e1",
283
+ "0x1b8F28C0d410456FE04b8f421d00d6654F66AbB6",
284
+ # fake DAI
285
+ "0xf84f908E78f9295b53883AD9ACa38F86d513f03F",
286
+ "0x20Dd160716b0387220Eea7B9951bDb51B3728DC4",
287
+ "0xd91AdE7B3c349815e427cf678837cC12F72d1d38",
288
+ "0xa362389216664668bC195f6BF1940d3754914219",
289
+ # fake USDT
290
+ "0x9257Cf49802E00048A30a6429e9c4d86210F4253",
291
+ "0x6b1b80b4b3228060EA21C292a3b9c576691Ca6cC",
292
+ "0xfCDFf724385Dcb47f2E62f7F2E383a7822Ed9718",
293
+ "0x94a2a4d842F522Dac0E793f2f9Ad08058997D06d",
294
+ "0xb44D28295E3D7C898C087A1cB209A444DeD5E4c1",
295
+ "0xFf3A7EE33203F5d3C69C309B5425b0E3fEfB736B",
296
+ # fake ETH
297
+ "0x225795bb6D20773a4A34c682Ae8457D00C80F955",
298
+ "0x25741E94782d3EaA7fb0A02D78256bf065AEC3B9",
299
+ # fake AERO
300
+ "0x3C78E3391C47fB9310BDB9085955934E1622442f",
301
+ "0x1f186De364a56e741Fcb188d37a393d409D08AeA",
302
+ "0xDd62542e9Be4390147f8c1f5b417f50ec4F834B7",
303
+ ],
304
+ Network.Fantom: [
305
+ # generally looks like shit
306
+ "0x630277E37fd2Ddf81e4683f3692dD817aa6225Cb",
307
+ ],
308
+ Network.Optimism: [
309
+ "0x168fbA6072EE467931484a418EDeb5FcC1B9fb79",
310
+ "0x04788E66B9D884969538e4e35a0D57e9e022c799",
311
+ "0x6Cad3dE073FD85567c0Df84063c8990855710677",
312
+ "0x109390594d0ef9B40B4B745Cac6ceCf37a179417",
313
+ "0x87f4b57E2d3c8C9dCD85aD9dA80129f92754b19f",
314
+ "0x1828Bff08BD244F7990edDCd9B19cc654b33cDB4",
315
+ "0xd8dAE0aD69F4aDB507dB0C3e56Ec94942D470450",
316
+ ],
317
+ Network.Arbitrum: [
318
+ "0xA57D85481B9ecD864F542Ea37bAA79A101a4f599",
319
+ "0x73fcaFc42ABB43A408bdE4b37eAfCCDadCB2b554",
320
+ "0x13577D823114697289cf85d3f563a21417022e7C",
321
+ "0xb8f2A48362371F7B4E88460BD4B3B5dba48A344f",
322
+ "0x184deAc2B1052AcB020Fa5159683733be3447699",
323
+ "0xBE9460b50f515169E14545aaddF60B3C9dB7e5Fb",
324
+ "0x8fb95D642C19a9C5C9138C5b444455A69196F2EC",
325
+ "0x1d7edf990Cd21eaB14aA55f8d06a386c73D24B5B",
326
+ "0x96C708e060CdC5B8C6Ac6a015db0b10833F74157",
327
+ "0x4dB2207C2cf35aA5ecFE61c5d098Bb3e3Ed1a7B0",
328
+ "0x17c074e90372aC53FF98cA24c3745E6E38717C14",
329
+ "0xA4468e55c5723C2346484f6a01da7b8826EEeC1b",
330
+ "0xdf109e2b175038c66e074BfEacF37D7b0f3e426c",
331
+ "0xeCd434A1391c208C3Cf4D8aa0e91FCd7B84D2B91",
332
+ "0xef7aA9F26F586a96F3C7E2E5308296aAD56E7F30",
333
+ "0xd8b86C2d30101848Ffb9eB0D4019b94De13374CC",
334
+ "0x43566AeD154526E2d62B60Fc9d31C98d4feaf99c",
335
+ ],
336
+ }
337
+
338
+ SHITCOINS: DefaultDict[Network, set[ChecksumAddress]] = defaultdict(set)
339
+ """A dictionary that contains, for each chain, a set of shitcoins that will be fully ignored by eth_portfolio. Add your own shitcoins to this object to boost eth_portfolio's performance."""
340
+
341
+ for chain, tokens in shitcoins.items():
342
+ SHITCOINS[chain].update(convert.to_address(token) for token in tokens)
Binary file
@@ -0,0 +1,42 @@
1
+ from collections import defaultdict
2
+ from typing import DefaultDict, Final
3
+
4
+ from eth_typing import ChecksumAddress
5
+ from y import Network, convert
6
+
7
+ stableish: Final = {
8
+ Network.Mainnet: [
9
+ "0x674C6Ad92Fd080e4004b2312b45f796a192D27a0", # USDN
10
+ "0x1456688345527bE1f37E9e627DA0837D6f08C925", # USDP
11
+ "0x865377367054516e17014CcdED1e7d814EDC9ce4", # DOLA
12
+ "0x5f98805A4E8be255a32880FDeC7F6728C6568bA0", # LUSD
13
+ "0xB9D7DdDca9a4AC480991865EfEf82E01273F79C3", # bLUSD
14
+ "0x4Fabb145d64652a948d72533023f6E7A623C7C53", # BUSD
15
+ "0x853d955aCEf822Db058eb8505911ED77F175b99e", # FRAX
16
+ "0x5BC25f649fc4e26069dDF4cF4010F9f706c23831", # DUSD
17
+ "0x99D8a9C45b2ecA8864373A26D1459e3Dff1e17F3", # MIM
18
+ "0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd", # GUSD
19
+ "0x03ab458634910AaD20eF5f1C8ee96F1D6ac54919", # RAI
20
+ "0x2A8e1E676Ec238d8A992307B495b45B3fEAa5e86", # OUSD
21
+ "0x57Ab1ec28D129707052df4dF418D58a2D46d5f51", # sUSD
22
+ "0xe2f2a5C287993345a840Db3B0845fbC70f5935a5", # mUSD
23
+ "0x5B3b5DF2BF2B6543f78e053bD91C4Bdd820929f1", # USDM
24
+ "0xdF574c24545E5FfEcb9a659c229253D4111d87e1", # HUSD
25
+ "0xa47c8bf37f92aBed4A126BDA807A7b7498661acD", # UST
26
+ "0x4591DBfF62656E7859Afe5e45f6f47D3669fBB28", # mkUSD
27
+ "0x6c3ea9036406852006290770BEdFcAbA0e23A0e8", # PYUSD
28
+ "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E", # crvUSD
29
+ "0xBC6DA0FE9aD5f3b0d58160288917AA56653660E9", # alUSD
30
+ "0x40D16FC0246aD3160Ccc09B8D0D3A2cD28aE6C2f", # GHO
31
+ ],
32
+ }
33
+
34
+ STABLEISH_COINS: DefaultDict[int, set[ChecksumAddress]] = defaultdict(set)
35
+ """
36
+ A dictionary that contains, for each chain, a set of 'stable-ish' coins that are considered stable by the wider market but not by ypriceamgic.
37
+
38
+ These coins, and wrapper tokens that contain them, will be considered stablecoins on all dashboards.
39
+ """
40
+
41
+ for chain, tokens in stableish.items():
42
+ STABLEISH_COINS[chain].update(convert.to_address(token) for token in tokens)
@@ -0,0 +1,72 @@
1
+ from importlib import import_module
2
+ from inspect import getmodule, stack
3
+ from pkgutil import walk_packages
4
+ from types import ModuleType
5
+ from typing import Final
6
+
7
+ import y.constants
8
+
9
+ CHAINID: Final = y.constants.CHAINID
10
+
11
+
12
+ def get_submodules_for_module(module: ModuleType) -> list[ModuleType]:
13
+ """
14
+ Returns a list of submodules of `module`.
15
+ """
16
+ assert isinstance(module, ModuleType), "`module` must be a module"
17
+ return [
18
+ obj
19
+ for obj in module.__dict__.values()
20
+ if isinstance(obj, ModuleType) and obj.__name__.startswith(module.__name__)
21
+ ]
22
+
23
+
24
+ def get_class_defs_from_module(module: ModuleType) -> list[type]:
25
+ """
26
+ Returns a list of class definitions from a module.
27
+ """
28
+ return [
29
+ obj
30
+ for obj in module.__dict__.values()
31
+ if isinstance(obj, type) and obj.__module__ == module.__name__
32
+ ]
33
+
34
+
35
+ def get_protocols() -> list[type]:
36
+ """
37
+ Used to initialize a submodule's class object.
38
+ Returns a list of initialized protocol objects.
39
+ """
40
+ called_from_module = getmodule(stack()[1][0])
41
+ assert called_from_module, "You can only call this function from a module"
42
+ components = [
43
+ module
44
+ for module in get_submodules_for_module(called_from_module)
45
+ if not module.__name__.endswith("._base")
46
+ ]
47
+ return [
48
+ cls()
49
+ for component in components
50
+ for cls in get_class_defs_from_module(component)
51
+ if cls
52
+ and not cls.__name__.startswith("_")
53
+ and cls.__name__ != "Lending"
54
+ and (not hasattr(cls, "networks") or CHAINID in cls.networks)
55
+ ]
56
+
57
+
58
+ def import_submodules() -> dict[str, ModuleType]:
59
+ """
60
+ Import all submodules of the module from which this was called, recursively.
61
+ Ignores submodules named `"base"`.
62
+ Returns a dict of `{module.__name__: module}`
63
+ """
64
+ called_from_module = getmodule(stack()[1][0])
65
+ if called_from_module is None:
66
+ return {}
67
+ parent = f"{called_from_module.__name__}."
68
+ return {
69
+ name: import_module(parent + name)
70
+ for loader, name, is_pkg in walk_packages(called_from_module.__path__) # type: ignore
71
+ if name != "base"
72
+ }
@@ -0,0 +1,215 @@
1
+ import logging
2
+ import sqlite3
3
+ from abc import abstractmethod
4
+ from collections.abc import AsyncGenerator, AsyncIterator
5
+ from datetime import datetime
6
+ from functools import cached_property
7
+ from typing import TYPE_CHECKING, Final, Generic, TypeVar
8
+
9
+ import dank_mids
10
+ from a_sync import ASyncGenericBase, ASyncIterable, ASyncIterator, as_yielded
11
+ from brownie import chain
12
+ from brownie.exceptions import ContractNotFound
13
+ from eth_typing import ChecksumAddress
14
+ from faster_async_lru import alru_cache
15
+ from faster_eth_abi.exceptions import InsufficientDataBytes
16
+ from pandas import DataFrame # type: ignore
17
+ from y import ERC20, Contract, Network
18
+ from y.constants import CHAINID, NETWORK_NAME
19
+ from y.datatypes import AddressOrContract, Block
20
+ from y.exceptions import (
21
+ CantFetchParam,
22
+ ContractNotVerified,
23
+ NodeNotSynced,
24
+ NonStandardERC20,
25
+ PriceError,
26
+ reraise_excs_with_extra_context,
27
+ yPriceMagicError,
28
+ )
29
+ from y.prices.magic import get_price
30
+
31
+ from eth_portfolio import _config, _decimal
32
+ from eth_portfolio.typing import _T
33
+
34
+ if TYPE_CHECKING:
35
+ from eth_portfolio.structs import LedgerEntry
36
+
37
+
38
+ logger: Final = logging.getLogger(__name__)
39
+
40
+ NON_STANDARD_ERC721: Final[list[ChecksumAddress]] = {
41
+ Network.Mainnet: ["0xb47e3cd837dDF8e4c57F05d70Ab865de6e193BBB"], # CryptoPunks
42
+ }.get(CHAINID, [])
43
+
44
+ SUPPRESS_ERROR_LOGS: Final[list[ChecksumAddress]] = {
45
+ # put tokens here when you don't expect them to price successfully and do not want to see the associated error logs
46
+ }.get(CHAINID, [])
47
+ """Put tokens here when you don't expect them to price successfully and do not want to see the associated error logs."""
48
+
49
+
50
+ async def get_buffered_chain_height() -> int:
51
+ """Returns an int equal to the current height of the chain minus `_config.REORG_BUFFER`."""
52
+ return await dank_mids.eth.get_block_number() - _config.REORG_BUFFER
53
+
54
+
55
+ class PandableList(list[_T]):
56
+ @cached_property
57
+ def df(self) -> DataFrame:
58
+ return self._df()
59
+
60
+ def _df(self) -> DataFrame:
61
+ """Override this method if you need to manipulate your dataframe before returning it."""
62
+ return DataFrame(self)
63
+
64
+
65
+ class Decimal(_decimal.Decimal):
66
+ """
67
+ I'm in the process of moving from floats to decimals, this will help be as I buidl.
68
+ """
69
+
70
+ # TODO i forget why I had this lol, should I delete?
71
+
72
+
73
+ async def _describe_err(token: AddressOrContract, block: Block | None) -> str:
74
+ """
75
+ Assembles a string used to provide as much useful information as possible in PriceError messages
76
+ """
77
+ try:
78
+ symbol = await ERC20(token, asynchronous=True).symbol
79
+ except NonStandardERC20:
80
+ symbol = None
81
+
82
+ if block is None:
83
+ if symbol:
84
+ return f"{symbol} {token} on {NETWORK_NAME}"
85
+
86
+ return f"malformed token {token} on {NETWORK_NAME}"
87
+
88
+ if symbol:
89
+ return f"{symbol} {token} on {NETWORK_NAME} at {block}"
90
+
91
+ return f"malformed token {token} on {NETWORK_NAME} at {block}"
92
+
93
+
94
+ _to_raise: Final = (
95
+ OSError,
96
+ FileNotFoundError,
97
+ NodeNotSynced,
98
+ NotImplementedError,
99
+ sqlite3.OperationalError,
100
+ InsufficientDataBytes,
101
+ UnboundLocalError,
102
+ RuntimeError,
103
+ )
104
+
105
+
106
+ async def _get_price(token: AddressOrContract, block: int | None = None) -> _decimal.Decimal:
107
+ token = str(token)
108
+ with reraise_excs_with_extra_context(token, block):
109
+ try:
110
+ if await is_erc721(token):
111
+ return _decimal.Decimal(0)
112
+ maybe_float = await get_price(token, block, silent=True, sync=False)
113
+ dprice = _decimal.Decimal(maybe_float)
114
+ return round(dprice, 18)
115
+ except CantFetchParam as e:
116
+ logger.warning("CantFetchParam %s", e)
117
+ except yPriceMagicError as e:
118
+ # Raise these exceptions
119
+ if isinstance(e.exception, _to_raise) and not isinstance(e.exception, RecursionError):
120
+ raise e.exception
121
+ # The exceptions below are acceptable enough
122
+ elif isinstance(e.exception, NonStandardERC20):
123
+ # Can't get symbol for handling like other excs
124
+ logger.warning(f"NonStandardERC20 while fetching price for {token}")
125
+ elif isinstance(e.exception, PriceError):
126
+ if token not in SUPPRESS_ERROR_LOGS:
127
+ logger.warning(
128
+ f"PriceError while fetching price for {await _describe_err(token, block)}"
129
+ )
130
+ else:
131
+ logger.warning(f"{e} while fetching price for {await _describe_err(token, block)}")
132
+ logger.warning(e, exc_info=True)
133
+ return _decimal.Decimal(0)
134
+
135
+
136
+ @alru_cache(maxsize=None)
137
+ async def is_erc721(token: ChecksumAddress) -> bool:
138
+ # This can probably be improved
139
+ try:
140
+ contract = await Contract.coroutine(token)
141
+ except (ContractNotFound, ContractNotVerified):
142
+ return False
143
+ attrs = "setApprovalForAll", "getApproved", "isApprovedForAll"
144
+ if all(hasattr(contract, attr) for attr in attrs):
145
+ return True
146
+ elif contract.address in NON_STANDARD_ERC721:
147
+ return True
148
+ return False
149
+
150
+
151
+ def _unpack_indicies(indicies: Block | tuple[Block, Block]) -> tuple[Block, Block]:
152
+ """Unpacks indicies and returns a tuple (start_block, end_block)."""
153
+ if isinstance(indicies, tuple):
154
+ start_block, end_block = indicies
155
+ else:
156
+ start_block = 0
157
+ end_block = indicies
158
+ return start_block, end_block
159
+
160
+
161
+ class _AiterMixin(ASyncIterable[_T]):
162
+ def __aiter__(self) -> AsyncIterator[_T]:
163
+ return self[self._start_block : chain.height].__aiter__()
164
+
165
+ def __getitem__(self, slice: slice) -> ASyncIterator[_T]:
166
+ if slice.start is not None and not isinstance(slice.start, (int, datetime)):
167
+ raise TypeError(f"start must be int or datetime. you passed {slice.start}")
168
+ if slice.stop and not isinstance(slice.stop, (int, datetime)):
169
+ raise TypeError(f"start must be int or datetime. you passed {slice.start}")
170
+ if slice.step is not None:
171
+ raise ValueError("You cannot use a step here.")
172
+ return ASyncIterator(self._get_and_yield(slice.start or 0, slice.stop, True)) # type: ignore [truthy-function]
173
+
174
+ def yield_forever(self, mem_cache: bool = True) -> ASyncIterator[_T]:
175
+ return ASyncIterator(self._get_and_yield(self._start_block or 0, None, mem_cache))
176
+
177
+ @abstractmethod
178
+ async def _get_and_yield(
179
+ self, start_block: Block, end_block: Block, mem_cache: bool
180
+ ) -> AsyncGenerator[_T, None]:
181
+ yield
182
+
183
+ @property
184
+ @abstractmethod
185
+ def _start_block(self) -> int: ...
186
+
187
+
188
+ _LT = TypeVar("_LT")
189
+
190
+
191
+ class _LedgeredBase(ASyncGenericBase, _AiterMixin["LedgerEntry"], Generic[_LT]):
192
+ """A mixin class for things with ledgers"""
193
+
194
+ transactions: _LT
195
+ internal_transfers: _LT
196
+ token_transfers: _LT
197
+
198
+ def __init__(self, start_block: Block) -> None:
199
+ self.start_block = start_block
200
+ super().__init__()
201
+
202
+ @property
203
+ def _start_block(self) -> Block:
204
+ # in the middle of refactoring this
205
+ return self.start_block
206
+
207
+ @cached_property
208
+ def _ledgers(self) -> tuple[_LT, _LT, _LT]:
209
+ """A tuple with the 3 ledgers (transactions, internal transfers, token transfers)"""
210
+ return self.transactions, self.internal_transfers, self.token_transfers
211
+
212
+ def _get_and_yield(
213
+ self, start_block: Block, end_block: Block, mem_cache: bool
214
+ ) -> AsyncGenerator["LedgerEntry", None]:
215
+ return as_yielded(*(ledger._get_and_yield(start_block, end_block, mem_cache) for ledger in self._ledgers)) # type: ignore [return-value,index]
File without changes