1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use alloy_primitives::Address;
use brontes_macros::discovery_impl;
use brontes_pricing::Protocol;

discovery_impl!(
    UniswapV2Discovery,
    crate::UniswapV2Factory::createPairCall,
    0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f,
    |deployed_address: Address, trace_index: u64, call_data: createPairCall, _| async move {
        let mut token_a = call_data.tokenA;
        let mut token_b = call_data.tokenB;
        if token_a > token_b {
            std::mem::swap(&mut token_a, &mut token_b)
        }

        vec![NormalizedNewPool {
            pool_address: deployed_address,
            trace_index,
            protocol: Protocol::UniswapV2,
            tokens: vec![token_a, token_b],
        }]
    }
);

discovery_impl!(
    UniswapV3Discovery,
    crate::UniswapV3Factory::createPoolCall,
    0x1F98431c8aD98523631AE4a59f267346ea31F984,
    |deployed_address: Address, trace_index: u64, call_data: createPoolCall, _| async move {
        let mut token_a = call_data.tokenA;
        let mut token_b = call_data.tokenB;

        if token_a > token_b {
            std::mem::swap(&mut token_a, &mut token_b)
        }

        vec![NormalizedNewPool {
            pool_address: deployed_address,
            trace_index,
            protocol: Protocol::UniswapV3,
            tokens: vec![token_a, token_b],
        }]
    }
);

#[cfg(test)]
mod tests {
    use alloy_primitives::{hex, Address, B256};
    use brontes_types::{normalized_actions::pool::NormalizedNewPool, Protocol};

    use crate::test_utils::ClassifierTestUtils;

    #[brontes_macros::test]
    async fn test_uniswap_v2_discovery() {
        let utils = ClassifierTestUtils::new().await;
        let tx =
            B256::new(hex!("16bba367585045f6c87ec2beca8243575d7a5891f58c1af5e70bc45de4d3e347"));

        let eq_create = NormalizedNewPool {
            trace_index:  1,
            protocol:     Protocol::UniswapV2,
            pool_address: Address::new(hex!("082366f442ea46a608f3c2c5e7abd5f53a86125b")),
            tokens:       vec![
                hex!("52c6889677E514BDD0f09E32003C15B33E88DccE").into(),
                hex!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2").into(),
            ],
        };

        utils
            .test_discovery_classification(
                tx,
                Address::new(hex!("082366f442ea46a608f3c2c5e7abd5f53a86125b")),
                |mut pool| {
                    assert_eq!(pool.len(), 1);
                    let pool = pool.remove(0);
                    assert_eq!(pool.protocol, eq_create.protocol);
                    assert_eq!(pool.pool_address, eq_create.pool_address);
                    assert_eq!(pool.tokens, eq_create.tokens);
                },
            )
            .await
            .unwrap();
    }

    #[brontes_macros::test]
    async fn test_uniswap_v3_discovery() {
        let utils = ClassifierTestUtils::new().await;
        let tx =
            B256::new(hex!("06c8ae6cc8705d3c6c8da07f2cb14af08ce981788ef237dcd204992ad207ddf1"));

        let eq_create = NormalizedNewPool {
            trace_index:  1,
            protocol:     Protocol::UniswapV3,
            pool_address: Address::new(hex!("602c70f43c7436975aec3113b316e7912d5ee2e3")),
            tokens:       vec![
                hex!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2").into(),
                hex!("edB357b55BC2DA1882B629EaDD3DF06202092d69").into(),
            ],
        };

        utils
            .test_discovery_classification(
                tx,
                Address::new(hex!("602c70f43c7436975aec3113b316e7912d5ee2e3")),
                |mut pool| {
                    assert_eq!(pool.len(), 1);
                    let pool = pool.remove(0);
                    assert_eq!(pool.protocol, eq_create.protocol);
                    assert_eq!(pool.pool_address, eq_create.pool_address);
                    assert_eq!(pool.tokens, eq_create.tokens);
                },
            )
            .await
            .unwrap();
    }
}