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