kabu_types_events/
swap_compose.rs1use crate::tx_compose::TxComposeData;
2use crate::Message;
3use alloy_eips::eip2718::Encodable2718;
4use alloy_primitives::{Bytes, TxHash, U256};
5use eyre::{eyre, Result};
6use kabu_types_blockchain::{KabuDataTypes, KabuDataTypesEthereum};
7use kabu_types_entities::{PoolId, Swap};
8use revm::DatabaseRef;
9use std::ops::Deref;
10
11#[derive(Clone, Debug)]
12pub enum TxState<LDT: KabuDataTypes = KabuDataTypesEthereum> {
13 Stuffing(LDT::Transaction),
14 SignatureRequired(LDT::TransactionRequest),
15 ReadyForBroadcast(Bytes),
16 ReadyForBroadcastStuffing(Bytes),
17}
18
19impl TxState {
20 pub fn rlp(&self) -> Result<Bytes> {
21 match self {
22 TxState::Stuffing(t) => Ok(Bytes::from(t.clone().inner.encoded_2718())),
23 TxState::ReadyForBroadcast(t) | TxState::ReadyForBroadcastStuffing(t) => Ok(t.clone()),
24 _ => Err(eyre!("NOT_READY_FOR_BROADCAST")),
25 }
26 }
27}
28
29#[derive(Clone, Debug)]
30pub enum SwapComposeMessage<DB, LDT: KabuDataTypes = KabuDataTypesEthereum> {
31 Prepare(SwapComposeData<DB, LDT>),
32 Estimate(SwapComposeData<DB, LDT>),
33 Ready(SwapComposeData<DB, LDT>),
34}
35
36impl<DB, LDT: KabuDataTypes> Deref for SwapComposeMessage<DB, LDT> {
37 type Target = SwapComposeData<DB, LDT>;
38
39 fn deref(&self) -> &Self::Target {
40 self.data()
41 }
42}
43
44impl<DB, LDT: KabuDataTypes> SwapComposeMessage<DB, LDT> {
45 pub fn data(&self) -> &SwapComposeData<DB, LDT> {
46 match self {
47 SwapComposeMessage::Prepare(x) | SwapComposeMessage::Estimate(x) | SwapComposeMessage::Ready(x) => x,
48 }
49 }
50}
51
52#[derive(Clone, Debug)]
53pub struct SwapComposeData<DB, LDT: KabuDataTypes = KabuDataTypesEthereum> {
54 pub tx_compose: TxComposeData<LDT>,
55 pub swap: Swap,
56 pub prestate: Option<DB>,
57 pub poststate: Option<DB>,
58 pub poststate_update: Option<Vec<LDT::StateUpdate>>,
59 pub origin: Option<String>,
60 pub tips_pct: Option<u32>,
61 pub tips: Option<U256>,
62}
63
64impl<DB: Clone + 'static, LDT: KabuDataTypes> SwapComposeData<DB, LDT> {
65 pub fn same_stuffing(&self, others_stuffing_txs_hashes: &[TxHash]) -> bool {
66 let tx_len = self.tx_compose.stuffing_txs_hashes.len();
67
68 if tx_len != others_stuffing_txs_hashes.len() {
69 false
70 } else if tx_len == 0 {
71 true
72 } else {
73 others_stuffing_txs_hashes.iter().all(|x| self.tx_compose.stuffing_txs_hashes.contains(x))
74 }
75 }
76
77 pub fn cross_pools(&self, others_pools: &[PoolId]) -> bool {
78 self.swap.get_pool_id_vec().iter().any(|x| others_pools.contains(x))
79 }
80
81 pub fn first_stuffing_hash(&self) -> TxHash {
82 self.tx_compose.stuffing_txs_hashes.first().map_or(TxHash::default(), |x| *x)
83 }
84
85 pub fn tips_gas_ratio(&self) -> U256 {
86 if self.tx_compose.gas == 0 {
87 U256::ZERO
88 } else {
89 self.tips.unwrap_or_default() / U256::from(self.tx_compose.gas)
90 }
91 }
92
93 pub fn profit_eth_gas_ratio(&self) -> U256 {
94 if self.tx_compose.gas == 0 {
95 U256::ZERO
96 } else {
97 self.swap.arb_profit_eth() / U256::from(self.tx_compose.gas)
98 }
99 }
100
101 pub fn gas_price(&self) -> u128 {
102 self.tx_compose.next_block_base_fee as u128 + self.tx_compose.priority_gas_fee as u128
103 }
104
105 pub fn gas_cost(&self) -> u128 {
106 self.tx_compose.gas as u128 * (self.tx_compose.next_block_base_fee as u128 + self.tx_compose.priority_gas_fee as u128)
107 }
108}
109
110impl<DB: DatabaseRef + Send + Sync + Clone + 'static, LDT: KabuDataTypes> Default for SwapComposeData<DB, LDT> {
111 fn default() -> Self {
112 Self {
113 tx_compose: Default::default(),
114 swap: Swap::None,
115 prestate: None,
116 poststate: None,
117 poststate_update: None,
118 origin: None,
119 tips_pct: None,
120 tips: None,
121 }
122 }
123}
124
125pub type MessageSwapCompose<DB, LDT = KabuDataTypesEthereum> = Message<SwapComposeMessage<DB, LDT>>;
126
127impl<DB, LDT: KabuDataTypes> MessageSwapCompose<DB, LDT> {
128 pub fn prepare(data: SwapComposeData<DB, LDT>) -> Self {
129 Message::new(SwapComposeMessage::Prepare(data))
130 }
131
132 pub fn estimate(data: SwapComposeData<DB, LDT>) -> Self {
133 Message::new(SwapComposeMessage::Estimate(data))
134 }
135
136 pub fn ready(data: SwapComposeData<DB, LDT>) -> Self {
137 Message::new(SwapComposeMessage::Ready(data))
138 }
139}