1pub mod blockchain;
2pub mod contract;
3pub mod error;
4pub mod protocol;
5pub mod token;
6
7use std::{collections::HashMap, fmt::Display, str::FromStr};
8
9use deepsize::DeepSizeOf;
10use serde::{Deserialize, Serialize};
11use strum_macros::{Display, EnumString};
12use thiserror::Error;
13use token::Token;
14
15use crate::{dto, Bytes};
16
17pub type Address = Bytes;
20
21pub type BlockHash = Bytes;
24
25pub type TxHash = Bytes;
28
29pub type Code = Bytes;
31
32pub type CodeHash = Bytes;
34
35pub type Balance = Bytes;
37
38pub type StoreKey = Bytes;
40
41pub type AttrStoreKey = String;
43
44pub type StoreVal = Bytes;
46
47pub type ContractStore = HashMap<StoreKey, StoreVal>;
49pub type ContractStoreDeltas = HashMap<StoreKey, Option<StoreVal>>;
50pub type AccountToContractStoreDeltas = HashMap<Address, ContractStoreDeltas>;
51
52pub type ComponentId = String;
54
55pub type ProtocolSystem = String;
57
58pub type EntryPointId = String;
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
67pub enum TvlThresholdTier {
68 Low,
70 Medium,
72}
73
74#[derive(
75 Debug,
76 Clone,
77 Copy,
78 PartialEq,
79 Eq,
80 Hash,
81 Serialize,
82 Deserialize,
83 EnumString,
84 Display,
85 Default,
86 DeepSizeOf,
87)]
88#[serde(rename_all = "lowercase")]
89#[strum(serialize_all = "lowercase")]
90pub enum Chain {
91 #[default]
92 Ethereum,
93 Starknet,
94 ZkSync,
95 Arbitrum,
96 Base,
97 Bsc,
98 Unichain,
99 Polygon,
100}
101
102impl From<dto::Chain> for Chain {
103 fn from(value: dto::Chain) -> Self {
104 match value {
105 dto::Chain::Ethereum => Chain::Ethereum,
106 dto::Chain::Starknet => Chain::Starknet,
107 dto::Chain::ZkSync => Chain::ZkSync,
108 dto::Chain::Arbitrum => Chain::Arbitrum,
109 dto::Chain::Base => Chain::Base,
110 dto::Chain::Bsc => Chain::Bsc,
111 dto::Chain::Unichain => Chain::Unichain,
112 dto::Chain::Polygon => Chain::Polygon,
113 }
114 }
115}
116
117impl From<dto::ChangeType> for ChangeType {
118 fn from(value: dto::ChangeType) -> Self {
119 match value {
120 dto::ChangeType::Update => ChangeType::Update,
121 dto::ChangeType::Creation => ChangeType::Creation,
122 dto::ChangeType::Deletion => ChangeType::Deletion,
123 dto::ChangeType::Unspecified => ChangeType::Update,
124 }
125 }
126}
127
128fn native_eth(chain: Chain) -> Token {
129 Token::new(
130 &Bytes::from_str("0x0000000000000000000000000000000000000000").unwrap(),
131 "ETH",
132 18,
133 0,
134 &[Some(2300)],
135 chain,
136 100,
137 )
138}
139
140fn native_bsc(chain: Chain) -> Token {
141 Token::new(
142 &Bytes::from_str("0x0000000000000000000000000000000000000000").unwrap(),
143 "BNB",
144 18,
145 0,
146 &[Some(2300)],
147 chain,
148 100,
149 )
150}
151
152fn wrapped_native_eth(chain: Chain, address: &str) -> Token {
153 Token::new(&Bytes::from_str(address).unwrap(), "WETH", 18, 0, &[Some(2300)], chain, 100)
154}
155
156fn native_pol(chain: Chain) -> Token {
157 Token::new(
158 &Bytes::from_str("0x0000000000000000000000000000000000000000").unwrap(),
159 "POL",
160 18,
161 0,
162 &[Some(2300)],
163 chain,
164 100,
165 )
166}
167
168fn wrapped_native_bsc(chain: Chain, address: &str) -> Token {
169 Token::new(&Bytes::from_str(address).unwrap(), "WBNB", 18, 0, &[Some(2300)], chain, 100)
170}
171
172fn wrapped_native_pol(chain: Chain, address: &str) -> Token {
173 Token::new(&Bytes::from_str(address).unwrap(), "WMATIC", 18, 0, &[Some(2300)], chain, 100)
174}
175
176impl Chain {
177 pub fn id(&self) -> u64 {
178 match self {
179 Chain::Ethereum => 1,
180 Chain::ZkSync => 324,
181 Chain::Arbitrum => 42161,
182 Chain::Starknet => 0,
183 Chain::Base => 8453,
184 Chain::Bsc => 56,
185 Chain::Unichain => 130,
186 Chain::Polygon => 137,
187 }
188 }
189
190 pub fn default_tvl_threshold(&self, tier: TvlThresholdTier) -> f64 {
197 match (self, tier) {
198 (
201 Chain::Ethereum |
202 Chain::Starknet |
203 Chain::ZkSync |
204 Chain::Arbitrum |
205 Chain::Base |
206 Chain::Unichain,
207 TvlThresholdTier::Low,
208 ) => 10.0,
209 (
210 Chain::Ethereum |
211 Chain::Starknet |
212 Chain::ZkSync |
213 Chain::Arbitrum |
214 Chain::Base |
215 Chain::Unichain,
216 TvlThresholdTier::Medium,
217 ) => 100.0,
218
219 (Chain::Polygon, TvlThresholdTier::Low) => 200_000.0,
221 (Chain::Polygon, TvlThresholdTier::Medium) => 2_000_000.0,
222
223 (Chain::Bsc, TvlThresholdTier::Low) => 32.0,
225 (Chain::Bsc, TvlThresholdTier::Medium) => 320.0,
226 }
227 }
228
229 pub fn native_token(&self) -> Token {
231 match self {
232 Chain::Ethereum => native_eth(Chain::Ethereum),
233 Chain::Starknet => native_eth(Chain::Starknet),
236 Chain::ZkSync => native_eth(Chain::ZkSync),
237 Chain::Arbitrum => native_eth(Chain::Arbitrum),
238 Chain::Base => native_eth(Chain::Base),
239 Chain::Bsc => native_bsc(Chain::Bsc),
240 Chain::Unichain => native_eth(Chain::Unichain),
241 Chain::Polygon => native_pol(Chain::Polygon),
242 }
243 }
244
245 pub fn wrapped_native_token(&self) -> Token {
247 match self {
248 Chain::Ethereum => {
249 wrapped_native_eth(Chain::Ethereum, "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
250 }
251 Chain::Starknet => {
253 wrapped_native_eth(Chain::Starknet, "0x0000000000000000000000000000000000000000")
254 }
255 Chain::ZkSync => {
256 wrapped_native_eth(Chain::ZkSync, "0x5AEa5775959fBC2557Cc8789bC1bf90A239D9a91")
257 }
258 Chain::Arbitrum => {
259 wrapped_native_eth(Chain::Arbitrum, "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1")
260 }
261 Chain::Base => {
262 wrapped_native_eth(Chain::Base, "0x4200000000000000000000000000000000000006")
263 }
264 Chain::Bsc => {
265 wrapped_native_bsc(Chain::Bsc, "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c")
266 }
267 Chain::Unichain => {
268 wrapped_native_eth(Chain::Unichain, "0x4200000000000000000000000000000000000006")
269 }
270 Chain::Polygon => {
271 wrapped_native_pol(Chain::Polygon, "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270")
272 }
273 }
274 }
275}
276
277#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, Default)]
278pub struct ExtractorIdentity {
279 pub chain: Chain,
280 pub name: String,
281}
282
283impl ExtractorIdentity {
284 pub fn new(chain: Chain, name: &str) -> Self {
285 Self { chain, name: name.to_owned() }
286 }
287}
288
289impl std::fmt::Display for ExtractorIdentity {
290 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
291 write!(f, "{}:{}", self.chain, self.name)
292 }
293}
294
295impl From<ExtractorIdentity> for dto::ExtractorIdentity {
296 fn from(value: ExtractorIdentity) -> Self {
297 dto::ExtractorIdentity { chain: value.chain.into(), name: value.name }
298 }
299}
300
301impl From<dto::ExtractorIdentity> for ExtractorIdentity {
302 fn from(value: dto::ExtractorIdentity) -> Self {
303 Self { chain: value.chain.into(), name: value.name }
304 }
305}
306
307#[derive(Debug, PartialEq, Clone)]
308pub struct ExtractionState {
309 pub name: String,
310 pub chain: Chain,
311 pub attributes: serde_json::Value,
312 pub cursor: Vec<u8>,
313 pub block_hash: Bytes,
314}
315
316impl ExtractionState {
317 pub fn new(
318 name: String,
319 chain: Chain,
320 attributes: Option<serde_json::Value>,
321 cursor: &[u8],
322 block_hash: Bytes,
323 ) -> Self {
324 ExtractionState {
325 name,
326 chain,
327 attributes: attributes.unwrap_or_default(),
328 cursor: cursor.to_vec(),
329 block_hash,
330 }
331 }
332}
333
334#[derive(PartialEq, Debug, Clone, Default, Deserialize, Serialize)]
335pub enum ImplementationType {
336 #[default]
337 Vm,
338 Custom,
339}
340
341#[derive(PartialEq, Debug, Clone, Default, Deserialize, Serialize)]
342pub enum FinancialType {
343 #[default]
344 Swap,
345 Psm,
346 Debt,
347 Leverage,
348}
349
350#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
351pub struct ProtocolType {
352 pub name: String,
353 pub financial_type: FinancialType,
354 pub attribute_schema: Option<serde_json::Value>,
355 pub implementation: ImplementationType,
356}
357
358impl ProtocolType {
359 pub fn new(
360 name: String,
361 financial_type: FinancialType,
362 attribute_schema: Option<serde_json::Value>,
363 implementation: ImplementationType,
364 ) -> Self {
365 ProtocolType { name, financial_type, attribute_schema, implementation }
366 }
367}
368
369#[derive(Debug, PartialEq, Eq, Default, Copy, Clone, Deserialize, Serialize, DeepSizeOf)]
370pub enum ChangeType {
371 #[default]
372 Update,
373 Deletion,
374 Creation,
375}
376
377#[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
378pub struct ContractId {
379 pub address: Address,
380 pub chain: Chain,
381}
382
383impl ContractId {
385 pub fn new(chain: Chain, address: Address) -> Self {
386 Self { address, chain }
387 }
388
389 pub fn address(&self) -> &Address {
390 &self.address
391 }
392}
393
394impl Display for ContractId {
395 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
396 write!(f, "{:?}: 0x{}", self.chain, hex::encode(&self.address))
397 }
398}
399
400#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
401pub struct PaginationParams {
402 pub page: i64,
403 pub page_size: i64,
404}
405
406impl PaginationParams {
407 pub fn new(page: i64, page_size: i64) -> Self {
408 Self { page, page_size }
409 }
410
411 pub fn offset(&self) -> i64 {
412 self.page * self.page_size
413 }
414}
415
416impl From<&dto::PaginationParams> for PaginationParams {
417 fn from(value: &dto::PaginationParams) -> Self {
418 PaginationParams { page: value.page, page_size: value.page_size }
419 }
420}
421
422#[derive(Error, Debug, PartialEq)]
423pub enum MergeError {
424 #[error("Can't merge {0} from differring idendities: Expected {1}, got {2}")]
425 IdMismatch(String, String, String),
426 #[error("Can't merge {0} from different blocks: 0x{1:x} != 0x{2:x}")]
427 BlockMismatch(String, Bytes, Bytes),
428 #[error("Can't merge {0} from the same transaction: 0x{1:x}")]
429 SameTransaction(String, Bytes),
430 #[error("Can't merge {0} with lower transaction index: {1} > {2}")]
431 TransactionOrderError(String, u64, u64),
432 #[error("Cannot merge: {0}")]
433 InvalidState(String),
434}