nautilus_blockchain/events/swap.rs
1// -------------------------------------------------------------------------------------------------
2// Copyright (C) 2015-2025 Nautech Systems Pty Ltd. All rights reserved.
3// https://nautechsystems.io
4//
5// Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6// You may not use this file except in compliance with the License.
7// You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use alloy::primitives::{Address, I256, U160};
17use nautilus_core::UnixNanos;
18use nautilus_model::{
19 defi::{PoolSwap, SharedChain, SharedDex},
20 enums::OrderSide,
21 identifiers::InstrumentId,
22 types::{Price, Quantity},
23};
24
25/// Represents a token swap event from liquidity pools emitted from smart contract.
26///
27/// This struct captures the essential data from a swap transaction on decentralized
28/// exchanges (DEXs) that use automated market maker (AMM) protocols.
29#[derive(Debug, Clone)]
30pub struct SwapEvent {
31 /// The decentralized exchange where the event happened.
32 pub dex: SharedDex,
33 /// The address of the smart contract which emitted the event.
34 pub pool_address: Address,
35 /// The block number in which this swap transaction was included.
36 pub block_number: u64,
37 /// The unique hash identifier of the transaction containing this event.
38 pub transaction_hash: String,
39 /// The position of this transaction within the block.
40 pub transaction_index: u32,
41 /// The position of this event log within the transaction.
42 pub log_index: u32,
43 /// The address that initiated the swap transaction.
44 pub sender: Address,
45 /// The address that received the swapped tokens.
46 pub receiver: Address,
47 /// The amount of token0 involved in the swap.
48 /// Negative values indicate tokens flowing out of the pool, positive values indicate tokens flowing in.
49 pub amount0: I256,
50 /// The amount of token1 involved in the swap.
51 /// Negative values indicate tokens flowing out of the pool, positive values indicate tokens flowing in.
52 pub amount1: I256,
53 /// The square root of the price ratio encoded as a Q64.96 fixed-point number.
54 /// This represents the price of token1 in terms of token0 after the swap.
55 pub sqrt_price_x96: U160,
56}
57
58impl SwapEvent {
59 /// Creates a new [`SwapEvent`] instance with the specified parameters.
60 #[must_use]
61 #[allow(clippy::too_many_arguments)]
62 pub const fn new(
63 dex: SharedDex,
64 pool_address: Address,
65 block_number: u64,
66 transaction_hash: String,
67 transaction_index: u32,
68 log_index: u32,
69 sender: Address,
70 receiver: Address,
71 amount0: I256,
72 amount1: I256,
73 sqrt_price_x96: U160,
74 ) -> Self {
75 Self {
76 dex,
77 pool_address,
78 block_number,
79 transaction_hash,
80 transaction_index,
81 log_index,
82 sender,
83 receiver,
84 amount0,
85 amount1,
86 sqrt_price_x96,
87 }
88 }
89
90 /// Converts a swap event into a `PoolSwap`.
91 #[allow(clippy::too_many_arguments)]
92 #[must_use]
93 pub fn to_pool_swap(
94 &self,
95 chain: SharedChain,
96 instrument_id: InstrumentId,
97 pool_address: Address,
98 normalized_side: OrderSide,
99 normalized_quantity: Quantity,
100 normalized_price: Price,
101 timestamp: Option<UnixNanos>,
102 ) -> PoolSwap {
103 PoolSwap::new(
104 chain,
105 self.dex.clone(),
106 instrument_id,
107 pool_address,
108 self.block_number,
109 self.transaction_hash.clone(),
110 self.transaction_index,
111 self.log_index,
112 timestamp,
113 self.sender,
114 normalized_side,
115 normalized_quantity,
116 normalized_price,
117 )
118 }
119}