pool_sync/pools/pool_structures/
balancer_v2_structure.rs1use alloy::primitives::FixedBytes;
2use alloy::primitives::U256;
3use alloy::rpc::types::Log;
4use alloy::sol_types::SolEvent;
5use alloy::{dyn_abi::DynSolValue, primitives::Address};
6use serde::{Deserialize, Serialize};
7
8use crate::pools::gen::Vault;
9#[derive(Debug, Clone, Serialize, Deserialize, Default)]
10pub struct BalancerV2Pool {
11 pub address: Address,
12 pub pool_id: FixedBytes<32>,
13 pub token0: Address,
14 pub token1: Address,
15 pub token0_name: String,
16 pub token1_name: String,
17 pub token0_decimals: u8,
18 pub token1_decimals: u8,
19 pub additional_tokens: Vec<Address>,
20 pub additional_token_names: Vec<String>,
21 pub additional_token_decimals: Vec<u8>,
22 pub balances: Vec<U256>,
23 pub weights: Vec<U256>,
24 pub swap_fee: U256,
25}
26
27impl BalancerV2Pool {
28 pub fn get_tokens(&self) -> Vec<Address> {
29 let mut tokens = vec![self.token0, self.token1];
30 tokens.extend(self.additional_tokens.iter());
31 tokens
32 }
33
34 pub fn get_token_index(&self, token: &Address) -> Option<usize> {
35 if *token == self.token0 {
36 Some(0)
37 } else if *token == self.token1 {
38 Some(1)
39 } else {
40 self.additional_tokens
41 .iter()
42 .position(|&t| t == *token)
43 .map(|pos| pos + 2)
44 }
45 }
46
47 pub fn get_balance(&self, token: &Address) -> U256 {
48 let index = self.get_token_index(token);
49 if let Some(index) = index {
50 self.balances[index]
51 } else {
52 U256::ZERO
53 }
54 }
55}
56
57pub fn process_balance_data(pool: &mut BalancerV2Pool, log: Log) {
58 let event = Vault::Swap::decode_log(log.as_ref(), true).unwrap();
59
60 let log_token_in_idx = pool.get_token_index(&event.tokenIn).unwrap();
61 let log_token_out_idx = pool.get_token_index(&event.tokenOut).unwrap();
62
63 pool.balances[log_token_in_idx] =
64 pool.balances[log_token_in_idx].saturating_add(event.amountIn);
65 pool.balances[log_token_out_idx] =
66 pool.balances[log_token_out_idx].saturating_sub(event.amountOut);
67}
68
69impl From<&[DynSolValue]> for BalancerV2Pool {
70 fn from(data: &[DynSolValue]) -> Self {
71 let pool_address = data[0].as_address().unwrap();
72 let pool_id = FixedBytes::from_slice(data[1].as_fixed_bytes().unwrap().0);
73 let token0 = data[2].as_address().unwrap();
74 let token1 = data[3].as_address().unwrap();
75 let token0_decimals = data[4].as_uint().unwrap().0.to::<u8>();
76 let token1_decimals = data[5].as_uint().unwrap().0.to::<u8>();
77 let additional_tokens: Vec<Address> = data[6]
78 .as_array()
79 .unwrap()
80 .iter()
81 .map(|v| v.as_address().unwrap())
82 .collect();
83 let additional_token_decimals: Vec<u8> = data[7]
84 .as_array()
85 .unwrap()
86 .iter()
87 .map(|v| v.as_uint().unwrap().0.to::<u8>())
88 .collect();
89 let balances: Vec<U256> = data[8]
90 .as_array()
91 .unwrap()
92 .iter()
93 .map(|v| v.as_uint().unwrap().0)
94 .collect();
95 let weights: Vec<U256> = data[9]
96 .as_array()
97 .unwrap()
98 .iter()
99 .map(|v| v.as_uint().unwrap().0)
100 .collect();
101 let swap_fee = data[10].as_uint().unwrap().0;
102
103 Self {
104 address: pool_address,
105 pool_id,
106 token0,
107 token1,
108 token0_name: String::new(), token1_name: String::new(), token0_decimals,
111 token1_decimals,
112 additional_tokens,
113 additional_token_names: Vec::new(), additional_token_decimals,
115 balances,
116 weights,
117 swap_fee,
118 }
119 }
120}
121