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}