kabu_anvil/test_config/
mod.rs1use std::collections::HashMap;
2
3use alloy_primitives::{Address, TxHash};
4use eyre::Result;
5use serde::Deserialize;
6use tokio::fs;
7
8use kabu::types::entities::PoolClass;
9
10#[derive(Deserialize, Debug)]
11pub struct TestConfig {
12 pub modules: Modules,
13 pub settings: Settings,
14 pub pools: HashMap<String, PoolConfig>,
15 pub txs: HashMap<String, TransactionConfig>,
16 pub tokens: HashMap<String, TokenConfig>,
17 pub assertions: AssertionsConfig,
18}
19
20fn default_true() -> bool {
21 true
22}
23fn default_false() -> bool {
24 false
25}
26
27#[allow(dead_code)]
28#[derive(Default, Deserialize, Debug, Clone)]
29pub struct AssertionsConfig {
30 pub swaps_encoded: Option<usize>,
31 pub swaps_ok: Option<usize>,
32 pub best_profit_eth: Option<f64>,
33}
34
35#[allow(dead_code)]
36#[derive(Deserialize, Debug)]
37pub struct Modules {
38 #[serde(default = "default_true")]
39 pub price: bool,
40 #[serde(default = "default_true")]
41 pub signer: bool,
42 #[serde(default = "default_true")]
43 pub encoder: bool,
44 #[serde(default = "default_true")]
45 pub arb_path_merger: bool,
46 #[serde(default = "default_true")]
47 pub same_path_merger: bool,
48 #[serde(default = "default_true")]
49 pub diff_path_merger: bool,
50 #[serde(default)]
51 pub arb_block: bool,
52 #[serde(default = "default_true")]
53 pub arb_mempool: bool,
54 #[serde(default = "default_false")]
55 pub flashbots: bool,
56}
57
58#[allow(dead_code)]
59#[derive(Deserialize, Debug)]
60pub struct Settings {
61 pub block: u64,
62 pub coinbase: Option<Address>,
63 pub multicaller: Option<Address>,
64}
65
66#[derive(Deserialize, Debug)]
67pub struct PoolConfig {
68 pub address: Address,
69 pub class: PoolClass,
70}
71
72#[derive(Deserialize, Debug)]
73pub struct TransactionConfig {
74 pub hash: TxHash,
75 pub send: String,
76}
77
78#[derive(Deserialize, Debug)]
79pub struct TokenConfig {
80 pub address: Address,
81 pub symbol: Option<String>,
82 pub name: Option<String>,
83 pub decimals: Option<u8>,
84 pub basic: Option<bool>,
85 pub middle: Option<bool>,
86 pub price: Option<f64>,
87}
88
89impl TestConfig {
90 pub async fn from_file(filename: String) -> Result<TestConfig> {
91 let toml_content = fs::read_to_string(filename.as_str()).await?;
92 let config: TestConfig = toml::from_str(&toml_content)?;
93 Ok(config)
94 }
95}
96
97#[cfg(test)]
98mod test {
99 use crate::test_config::TestConfig;
100
101 #[test]
102 fn test_deserialization() {
103 let cfg = r#"
104[settings]
105block = 19101579
106coinbase = "0x1dd35b4da6534230ff53048f7477f17f7f4e7a70"
107multicaller = "0x3dd35b4da6534230ff53048f7477f17f7f4e7a70"
108skip_default = false
109
110[modules]
111
112[pools]
113a = { address = "0x2dd35b4da6534230ff53048f7477f17f7f4e7a70", class = "uniswap2" }
114
115[txs]
116tx_1 = { hash = "0xf9fb98fe76dc5f4e836cdc3d80cd7902150a8609c617064f1447c3980fd6776b", send = "mempool" }
117tx_2 = { hash = "0x1ec982c2d4eb5475192b26f7208b797328eab88f8e5be053f797f74bcb87a20c", send = "mempool" }
118
119[tokens]
120weth = { address = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", symbol = "WETH", decimals = 18, basic = true, middle = false }
121
122[assertions]
123swaps_encoded = 14
124swaps_ok = 11
125best_profit_eth = 181.37
126 "#;
127 let config: TestConfig = toml::from_str(cfg).unwrap();
128 assert_eq!(config.settings.block, 19101579);
129 assert_eq!(config.assertions.swaps_encoded.unwrap_or_default(), 14);
130 assert_eq!(config.assertions.swaps_ok.unwrap_or_default(), 11);
131 assert_eq!(config.assertions.best_profit_eth.unwrap_or_default(), 181.37);
132 }
133}