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    identifiers::InstrumentId,
21};
22
23/// Represents a token swap event from liquidity pools emitted from smart contract.
24///
25/// This struct captures the essential data from a swap transaction on decentralized
26/// exchanges (DEXs) that use automated market maker (AMM) protocols.
27#[derive(Debug, Clone)]
28pub struct SwapEvent {
29    /// The decentralized exchange where the event happened.
30    pub dex: SharedDex,
31    /// The address of the smart contract which emitted the event.
32    pub pool_address: Address,
33    /// The block number in which this swap transaction was included.
34    pub block_number: u64,
35    /// The unique hash identifier of the transaction containing this event.
36    pub transaction_hash: String,
37    /// The position of this transaction within the block.
38    pub transaction_index: u32,
39    /// The position of this event log within the transaction.
40    pub log_index: u32,
41    /// The address that initiated the swap transaction.
42    pub sender: Address,
43    /// The address that received the swapped tokens.
44    pub receiver: Address,
45    /// The amount of token0 involved in the swap.
46    /// Negative values indicate tokens flowing out of the pool, positive values indicate tokens flowing in.
47    pub amount0: I256,
48    /// The amount of token1 involved in the swap.
49    /// Negative values indicate tokens flowing out of the pool, positive values indicate tokens flowing in.
50    pub amount1: I256,
51    /// The square root of the price ratio encoded as a Q64.96 fixed-point number.
52    /// This represents the price of token1 in terms of token0 after the swap.
53    pub sqrt_price_x96: U160,
54    /// The liquidity of the pool after the swap occurred.
55    pub liquidity: u128,
56    /// The current tick of the pool after the swap occurred.
57    pub tick: i32,
58}
59
60impl SwapEvent {
61    /// Creates a new [`SwapEvent`] instance with the specified parameters.
62    #[must_use]
63    #[allow(clippy::too_many_arguments)]
64    pub const fn new(
65        dex: SharedDex,
66        pool_address: Address,
67        block_number: u64,
68        transaction_hash: String,
69        transaction_index: u32,
70        log_index: u32,
71        sender: Address,
72        receiver: Address,
73        amount0: I256,
74        amount1: I256,
75        sqrt_price_x96: U160,
76        liquidity: u128,
77        tick: i32,
78    ) -> Self {
79        Self {
80            dex,
81            pool_address,
82            block_number,
83            transaction_hash,
84            transaction_index,
85            log_index,
86            sender,
87            receiver,
88            amount0,
89            amount1,
90            sqrt_price_x96,
91            liquidity,
92            tick,
93        }
94    }
95
96    /// Converts a swap event into a `PoolSwap`.
97    #[allow(clippy::too_many_arguments)]
98    #[must_use]
99    pub fn to_pool_swap(
100        &self,
101        chain: SharedChain,
102        instrument_id: InstrumentId,
103        pool_address: Address,
104        timestamp: Option<UnixNanos>,
105    ) -> PoolSwap {
106        PoolSwap::new(
107            chain,
108            self.dex.clone(),
109            instrument_id,
110            pool_address,
111            self.block_number,
112            self.transaction_hash.clone(),
113            self.transaction_index,
114            self.log_index,
115            timestamp,
116            self.sender,
117            self.receiver,
118            self.amount0,
119            self.amount1,
120            self.sqrt_price_x96,
121            self.liquidity,
122            self.tick,
123        )
124    }
125}