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
117
118
119
120
121
122
123
124
use brontes_macros::action_impl;
use brontes_pricing::Protocol;
use brontes_types::{normalized_actions::NormalizedAggregator, structured_trace::CallInfo};
use reth_primitives::Address;

action_impl!(
    Protocol::OneInchFusion,
    crate::OneInchFusionSettlement::settleOrdersCall,
    Aggregator,
    [],
    |info: CallInfo, _db_tx: &DB| {
        return Ok(NormalizedAggregator {
            protocol:      Protocol::OneInchFusion,
            trace_index:   info.trace_idx,
            from:          info.from_address,
            to:            info.target_address,
            recipient:     Address::default(),
            child_actions: vec![],
            msg_value:     info.msg_value,
        })
    }
);

#[cfg(test)]
mod tests {
    use std::str::FromStr;

    use alloy_primitives::{hex, B256, U256};
    use brontes_classifier::test_utils::ClassifierTestUtils;
    use brontes_types::{
        db::token_info::TokenInfoWithAddress,
        normalized_actions::{Action, NormalizedSwap, NormalizedTransfer},
        Protocol::{ClipperExchange, OneInchFusion},
        ToScaledRational, TreeSearchBuilder,
    };

    use super::*;

    #[brontes_macros::test]
    async fn test_one_inch_fusion_swap() {
        let classifier_utils = ClassifierTestUtils::new().await;
        let aggregator =
            B256::from(hex!("83860dfeec88e76c46cbfc945e6b3e80d2a355495f78567bdd91ee01e6220946"));

        let eq_action = Action::Aggregator(NormalizedAggregator {
            protocol:      OneInchFusion,
            trace_index:   0,
            to:            Address::new(hex!("a88800cd213da5ae406ce248380802bd53b47647")),
            from:          Address::new(hex!("D14699b6B02e900A5C2338700d5181a674FDB9a2")),
            recipient:     Address::new(hex!("d10F17699137DD6215c01F539726227fC042c9b2")),
            child_actions: vec![
                Action::Transfer(NormalizedTransfer {
                    trace_index: 5,
                    msg_value:   U256::ZERO,
                    from:        Address::new(hex!("d10f17699137dd6215c01f539726227fc042c9b2")),
                    to:          Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
                    token:       TokenInfoWithAddress::usdc(),
                    amount:      U256::from_str("269875186").unwrap().to_scaled_rational(6),
                    fee:         U256::from_str("0").unwrap().to_scaled_rational(1),
                }),
                Action::Transfer(NormalizedTransfer {
                    trace_index: 9,
                    msg_value:   U256::ZERO,
                    from:        Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
                    to:          Address::new(hex!("655edce464cc797526600a462a8154650eee4b77")),
                    token:       TokenInfoWithAddress::usdc(),
                    amount:      U256::from_str("269875186").unwrap().to_scaled_rational(6),
                    fee:         U256::from_str("0").unwrap().to_scaled_rational(1),
                }),
                Action::Swap(NormalizedSwap {
                    protocol:    ClipperExchange,
                    trace_index: 11,
                    from:        Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
                    recipient:   Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
                    pool:        Address::new(hex!("655edce464cc797526600a462a8154650eee4b77")),
                    token_in:    TokenInfoWithAddress::usdc(),
                    token_out:   TokenInfoWithAddress::usdt(),
                    amount_in:   U256::from_str("269875186").unwrap().to_scaled_rational(6),
                    amount_out:  U256::from_str("269716012").unwrap().to_scaled_rational(6),
                    msg_value:   U256::ZERO,
                }),
                Action::Transfer(NormalizedTransfer {
                    trace_index: 15,
                    from:        Address::new(hex!("655edce464cc797526600a462a8154650eee4b77")),
                    to:          Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
                    token:       TokenInfoWithAddress::usdt(),
                    amount:      U256::from_str("269716012").unwrap().to_scaled_rational(6),
                    fee:         U256::from_str("0").unwrap().to_scaled_rational(1),
                    msg_value:   U256::ZERO,
                }),
                Action::Transfer(NormalizedTransfer {
                    trace_index: 16,
                    from:        Address::new(hex!("235d3afac42f5e5ff346cb6c19af13194988551f")),
                    to:          Address::new(hex!("a88800cd213da5ae406ce248380802bd53b47647")),
                    token:       TokenInfoWithAddress::usdt(),
                    amount:      U256::from_str("216122672").unwrap().to_scaled_rational(6),
                    fee:         U256::from_str("0").unwrap().to_scaled_rational(1),
                    msg_value:   U256::ZERO,
                }),
                Action::Transfer(NormalizedTransfer {
                    trace_index: 18,
                    from:        Address::new(hex!("a88800cd213da5ae406ce248380802bd53b47647")),
                    to:          Address::new(hex!("d10f17699137dd6215c01f539726227fc042c9b2")),
                    token:       TokenInfoWithAddress::usdt(),
                    amount:      U256::from_str("216122672").unwrap().to_scaled_rational(6),
                    fee:         U256::from_str("0").unwrap().to_scaled_rational(1),
                    msg_value:   U256::ZERO,
                }),
            ],

            msg_value: U256::ZERO,
        });

        classifier_utils
            .contains_action(
                aggregator,
                0,
                eq_action,
                TreeSearchBuilder::default().with_action(Action::is_aggregator),
            )
            .await
            .unwrap();
    }
}