From 1d2acdcd671b2a948469e5632674fa52e7608fa9 Mon Sep 17 00:00:00 2001 From: Shuhui Luo <107524008+shuhuiluo@users.noreply.github.com> Date: Fri, 3 Jan 2025 00:24:46 -0500 Subject: [PATCH] refactor: clean up dependencies and re-exports (#92) * Remove `lazy_static` from prelude and add explicit imports. `lazy_static` was removed from the common prelude module to avoid unnecessary dependencies in files that don't require it. Explicit imports of `lazy_static` were added only where it is actually used, improving clarity and reducing potential overhead. * Refactor module structure and re-export logic for clarity Reorganized module layout to improve maintainability and simplify imports. Removed standalone `prelude.rs` by integrating its functionality directly into `lib.rs`. Adjusted tests, visibility modifiers, and re-export strategy across modules for cleaner and more efficient usage. * Refactor imports and improve type safety across the codebase Replaced unused or unnecessary imports with more relevant ones to optimize dependencies. Updated type usage for better clarity and correctness, including replacing `vec![]` with `[]` for `FxHashMap::from_iter` calls. Simplified assertions and improved error handling for better maintainability. * Update README and refactor type exports in library Updated the README to improve documentation order, clarify `no_std` usage, and enhance example formatting. Refactored type exports in the library to use type aliases for better readability and maintainability. --- Cargo.toml | 6 ++--- README.md | 22 ++++++++------- src/addresses.rs | 21 ++++++++------- src/constants.rs | 1 + src/entities/currency.rs | 1 + src/entities/ether.rs | 1 + src/entities/fractions/currency_amount.rs | 3 +++ src/entities/fractions/fraction.rs | 6 ++++- src/entities/fractions/mod.rs | 10 +++---- src/entities/fractions/percent.rs | 1 + src/entities/fractions/price.rs | 1 + src/entities/mod.rs | 8 ++++++ src/entities/token.rs | 6 ++--- src/entities/weth9.rs | 4 +-- src/examples/mod.rs | 2 +- src/examples/token_example.rs | 6 ++--- src/lib.rs | 20 +++++++++++--- src/prelude.rs | 33 ----------------------- src/utils/mod.rs | 5 ++++ src/utils/sorted_insert.rs | 3 ++- src/utils/sqrt.rs | 4 +-- 21 files changed, 84 insertions(+), 80 deletions(-) delete mode 100644 src/prelude.rs diff --git a/Cargo.toml b/Cargo.toml index e704554..803b62c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,22 +1,20 @@ [package] name = "uniswap-sdk-core" -version = "3.2.0" +version = "3.3.0" edition = "2021" authors = ["malik ", "Shuhui Luo "] description = "The Uniswap SDK Core in Rust provides essential functionality for interacting with the Uniswap decentralized exchange" license = "MIT" [dependencies] -alloy-primitives = "0.8" +alloy-primitives = { version = ">=0.8.5", features = ["map-fxhash"] } bigdecimal = "0.4.5" derive_more = { version = "1.0.0", features = ["deref"] } eth_checksum = { version = "0.1.2", optional = true } lazy_static = "1.5" num-bigint = "0.4" num-integer = "0.1" -num-traits = "0.2" regex = { version = "1.11", optional = true } -rustc-hash = "2.0" thiserror = { version = "2", default-features = false } [features] diff --git a/README.md b/README.md index 8bb6c6b..ce76b93 100644 --- a/README.md +++ b/README.md @@ -7,18 +7,13 @@ **A Custom Uniswap SDK Core in Rust provides essential functionality for interacting with the Uniswap decentralized exchange.** -## Note on `no_std` - -By default, this library does not depend on the standard library (`std`). However, the `std` feature can be enabled to -use `thiserror` for error handling. - ## Quickstart Add this to your Cargo.toml ``` [dependencies] -uniswap-sdk-core = "3.0.0" +uniswap-sdk-core = "3.3.0" ``` And this to your code: @@ -27,10 +22,15 @@ And this to your code: use uniswap_sdk_core::prelude::*; ``` +## Note on `no_std` + +By default, this library does not depend on the standard library (`std`). However, the `std` feature can be enabled. + ## Examples -The code below shows an example of how to create a new `Token` instance for the DAI token on the Ethereum Mainnet using -the `token!` macro. +
+ The code below shows an example of how to create a new `Token` instance for the DAI token on the Ethereum Mainnet using +the `token!` macro. ```rust // The `prelude` module provides a convenient way to import a number of common dependencies at @@ -68,6 +68,8 @@ fn main() { } ``` +
+ This example demonstrates how to create a `Token` instance for DAI on the Ethereum Mainnet using the `token!` macro. It then prints the token's address and checks if it's a native token (which it isn't, so it prints false). @@ -99,8 +101,8 @@ provide similar functionality in the Rust programming language. - [Uniswap V3 SDK Rust](https://github.com/shuhuiluo/uniswap-v3-sdk-rs): Opinionated Rust implementation of the Uniswap V3 SDK with a focus on readability and performance -- [Uniswap V2 SDK Rust](https://github.com/shuhuiluo/uniswap-v2-sdk-rs): Opinionated Rust implementation of the Uniswap - V2 SDK with a focus on readability and performance +- [Uniswap V4 SDK Rust](https://github.com/shuhuiluo/uniswap-v4-sdk-rs): Opinionated Rust implementation of the Uniswap + V4 SDK with a focus on readability and performance - ... *(If you want to add project to the list, dm or open a PR)* diff --git a/src/addresses.rs b/src/addresses.rs index 758864e..6f60c6f 100644 --- a/src/addresses.rs +++ b/src/addresses.rs @@ -1,7 +1,8 @@ use crate::prelude::*; -use alloc::vec; +use alloy_primitives::address; +use lazy_static::lazy_static; -type AddressMap = FxHashMap; +pub type AddressMap = FxHashMap; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] pub struct ChainAddresses { @@ -52,7 +53,7 @@ pub const V2_FACTORY_ADDRESS: Address = address!("5C69bEe701ef814a2B6a3EDD4B1652 lazy_static! { pub static ref V2_FACTORY_ADDRESSES: AddressMap = { - AddressMap::from_iter(vec![ + AddressMap::from_iter([ (ChainId::MAINNET as u64, V2_FACTORY_ADDRESS), (ChainId::GOERLI as u64, V2_FACTORY_ADDRESS), ( @@ -101,7 +102,7 @@ pub const V2_ROUTER_ADDRESS: Address = address!("7a250d5630B4cF539739dF2C5dAcb4c lazy_static! { pub static ref V2_ROUTER_ADDRESSES: AddressMap = { - AddressMap::from_iter(vec![ + AddressMap::from_iter([ (ChainId::MAINNET as u64, V2_ROUTER_ADDRESS), (ChainId::GOERLI as u64, V2_ROUTER_ADDRESS), ( @@ -381,7 +382,7 @@ lazy_static! { /// for a given network. The keys in the map are the network IDs, and the values /// are the corresponding contract addresses. pub static ref CHAIN_TO_ADDRESSES_MAP: FxHashMap = { - FxHashMap::from_iter(vec![ + FxHashMap::from_iter([ (ChainId::MAINNET as u64, MAINNET_ADDRESSES), (ChainId::OPTIMISM as u64, OPTIMISM_ADDRESSES), (ChainId::ARBITRUM_ONE as u64, ARBITUM_ONE_ADDRESSES), @@ -447,7 +448,7 @@ lazy_static! { lazy_static! { /// The older V1 governance address - pub static ref GOVERNANCE_ALPHA_V1_ADDRESSES: AddressMap = AddressMap::from_iter(vec![( + pub static ref GOVERNANCE_ALPHA_V1_ADDRESSES: AddressMap = AddressMap::from_iter([( ChainId::MAINNET as u64, address!("C4e172459f1E7939D522503B81AFAaC1014CE6F6") )]); @@ -455,7 +456,7 @@ lazy_static! { lazy_static! { /// The latest governor bravo that is currently admin of timelock - pub static ref GOVERNANCE_BRAVO_ADDRESSES: AddressMap = AddressMap::from_iter(vec![( + pub static ref GOVERNANCE_BRAVO_ADDRESSES: AddressMap = AddressMap::from_iter([( ChainId::MAINNET as u64, address!("408ED6354d4973f66138C91495F2f2FCbd8724C3") )]); @@ -467,14 +468,14 @@ lazy_static! { } lazy_static! { - pub static ref MERKLE_DISTRIBUTOR_ADDRESS: AddressMap = AddressMap::from_iter(vec![( + pub static ref MERKLE_DISTRIBUTOR_ADDRESS: AddressMap = AddressMap::from_iter([( ChainId::MAINNET as u64, address!("090D4613473dEE047c3f2706764f49E0821D256e"), )]); } lazy_static! { - pub static ref ARGENT_WALLET_DETECTOR_ADDRESS: AddressMap = AddressMap::from_iter(vec![( + pub static ref ARGENT_WALLET_DETECTOR_ADDRESS: AddressMap = AddressMap::from_iter([( ChainId::MAINNET as u64, address!("eca4B0bDBf7c55E9b7925919d03CbF8Dc82537E8"), )]); @@ -506,7 +507,7 @@ lazy_static! { } lazy_static! { - pub static ref SOCKS_CONTROLLER_ADDRESSES: AddressMap = AddressMap::from_iter(vec![( + pub static ref SOCKS_CONTROLLER_ADDRESSES: AddressMap = AddressMap::from_iter([( ChainId::MAINNET as u64, address!("65770b5283117639760beA3F867b69b3697a91dd") )]); diff --git a/src/constants.rs b/src/constants.rs index 5954b1c..dbce0a3 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,5 +1,6 @@ use crate::prelude::*; use alloy_primitives::U256; +use lazy_static::lazy_static; use num_bigint::Sign; /// Represents the various types of trades. diff --git a/src/entities/currency.rs b/src/entities/currency.rs index 180d192..3f5dd52 100644 --- a/src/entities/currency.rs +++ b/src/entities/currency.rs @@ -92,6 +92,7 @@ impl_base_currency!(Currency, &Currency); mod tests { use super::*; use crate::token; + use lazy_static::lazy_static; const ADDRESS_ZERO: &str = "0x0000000000000000000000000000000000000000"; const ADDRESS_ONE: &str = "0x0000000000000000000000000000000000000001"; diff --git a/src/entities/ether.rs b/src/entities/ether.rs index 5130168..9857632 100644 --- a/src/entities/ether.rs +++ b/src/entities/ether.rs @@ -1,4 +1,5 @@ use crate::prelude::*; +use alloc::string::ToString; /// Ether is the main usage of a 'native' currency, i.e., for Ethereum mainnet and all testnets. /// Represents the native currency of the blockchain. diff --git a/src/entities/fractions/currency_amount.rs b/src/entities/fractions/currency_amount.rs index 995942f..06a553c 100644 --- a/src/entities/fractions/currency_amount.rs +++ b/src/entities/fractions/currency_amount.rs @@ -1,5 +1,7 @@ use crate::prelude::*; +use alloc::string::ToString; use core::ops::Div; +use num_integer::Integer; /// Currency amount struct that represents a rational amount of a currency pub type CurrencyAmount = FractionLike>; @@ -154,6 +156,7 @@ impl CurrencyAmount { mod tests { use super::*; use crate::token; + use lazy_static::lazy_static; // Constants for testing const ADDRESS_ONE: &str = "0x0000000000000000000000000000000000000001"; diff --git a/src/entities/fractions/fraction.rs b/src/entities/fractions/fraction.rs index 843d798..25b7166 100644 --- a/src/entities/fractions/fraction.rs +++ b/src/entities/fractions/fraction.rs @@ -1,9 +1,13 @@ use crate::prelude::*; +use alloc::string::ToString; use core::{ + cmp::Ordering, hash::{Hash, Hasher}, + num::NonZeroU64, ops::{Add, Div, Mul, Sub}, }; use derive_more::Deref; +use num_integer::Integer; /// Struct representing a fraction with metadata #[derive(Clone, Debug, Deref)] @@ -162,7 +166,7 @@ impl FractionBase for FractionLike { #[inline] fn new(numerator: impl Into, denominator: impl Into, meta: M) -> Self { let denominator = denominator.into(); - assert!(!denominator.is_zero(), "denominator is zero"); + assert_ne!(denominator, BigInt::ZERO, "denominator is zero"); Self { numerator: numerator.into(), denominator, diff --git a/src/entities/fractions/mod.rs b/src/entities/fractions/mod.rs index 57485da..d82b0f0 100644 --- a/src/entities/fractions/mod.rs +++ b/src/entities/fractions/mod.rs @@ -1,9 +1,9 @@ -/// This module represents currency, including the currency type and the amount as a fraction. pub mod currency_amount; -/// This module contains with precise division results, avoiding floating-point arithmetic issues. pub mod fraction; -/// A module represents a percentage. pub mod percent; -/// A module represents a price as a ratio between two currencies, with methods for arithmetic and -/// string conversions. pub mod price; + +pub use currency_amount::*; +pub use fraction::*; +pub use percent::*; +pub use price::*; diff --git a/src/entities/fractions/percent.rs b/src/entities/fractions/percent.rs index dc4a808..0e5aea4 100644 --- a/src/entities/fractions/percent.rs +++ b/src/entities/fractions/percent.rs @@ -1,4 +1,5 @@ use crate::prelude::*; +use lazy_static::lazy_static; lazy_static! { static ref ONE_HUNDRED: Fraction = Fraction::new(100, 1); diff --git a/src/entities/fractions/price.rs b/src/entities/fractions/price.rs index 6e10c69..5bafc4d 100644 --- a/src/entities/fractions/price.rs +++ b/src/entities/fractions/price.rs @@ -142,6 +142,7 @@ where mod test { use super::*; use crate::token; + use lazy_static::lazy_static; const ADDRESS_ZERO: &str = "0x0000000000000000000000000000000000000000"; const ADDRESS_ONE: &str = "0x0000000000000000000000000000000000000001"; diff --git a/src/entities/mod.rs b/src/entities/mod.rs index 6e0c6df..71d9a74 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -5,3 +5,11 @@ pub mod fractions; pub mod native_currency; pub mod token; pub mod weth9; + +pub use base_currency::*; +pub use currency::*; +pub use ether::Ether; +pub use fractions::*; +pub use native_currency::NativeCurrency; +pub use token::*; +pub use weth9::WETH9; diff --git a/src/entities/token.rs b/src/entities/token.rs index 190b31e..79cdde6 100644 --- a/src/entities/token.rs +++ b/src/entities/token.rs @@ -131,7 +131,7 @@ macro_rules! token { ($chain_id:expr, $address:literal, $decimals:expr) => { Token::new( $chain_id, - address!($address), + alloy_primitives::address!($address), $decimals, None, None, @@ -153,7 +153,7 @@ macro_rules! token { ($chain_id:expr, $address:literal, $decimals:expr, $symbol:expr) => { Token::new( $chain_id, - address!($address), + alloy_primitives::address!($address), $decimals, Some($symbol.to_string()), None, @@ -175,7 +175,7 @@ macro_rules! token { ($chain_id:expr, $address:literal, $decimals:expr, $symbol:expr, $name:expr) => { Token::new( $chain_id, - address!($address), + alloy_primitives::address!($address), $decimals, Some($symbol.to_string()), Some($name.to_string()), diff --git a/src/entities/weth9.rs b/src/entities/weth9.rs index 177f280..46b4c15 100644 --- a/src/entities/weth9.rs +++ b/src/entities/weth9.rs @@ -1,5 +1,5 @@ use crate::{prelude::*, token}; -use alloc::vec; +use alloc::string::ToString; /// Represents the WETH9 contract and provides information about WETH tokens on different Ethereum /// chains. @@ -31,7 +31,7 @@ impl WETH9 { #[inline] #[must_use] pub fn new() -> Self { - let tokens = FxHashMap::from_iter(vec![ + let tokens = FxHashMap::from_iter([ (1, Self::on_chain(1).unwrap()), (3, Self::on_chain(3).unwrap()), (4, Self::on_chain(4).unwrap()), diff --git a/src/examples/mod.rs b/src/examples/mod.rs index 4b3de48..4b722ca 100644 --- a/src/examples/mod.rs +++ b/src/examples/mod.rs @@ -1 +1 @@ -pub mod token_example; +mod token_example; diff --git a/src/examples/token_example.rs b/src/examples/token_example.rs index 2a0e8c7..c76ecba 100644 --- a/src/examples/token_example.rs +++ b/src/examples/token_example.rs @@ -1,10 +1,8 @@ -#![cfg(test)] - -// Import the Token struct from the Uniswap SDK-Core use crate::entities::token::Token; /// This function demonstrates basic operations with the Token struct from the Uniswap SDK-Core. -pub fn main() { +#[test] +fn main() { // Create a new Token instance for DAI let dai_token = Token::new( 1, // Assuming chain_id is 1 for Ethereum mainnet diff --git a/src/lib.rs b/src/lib.rs index 21ff8e1..a0e7245 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,13 +36,25 @@ pub mod entities; /// This module defines custom error types that are used throughout the SDK to /// handle various error conditions. pub mod error; +/// Contains utility functions and helpers used across the Uniswap SDK Core. +pub mod utils; + /// Contains commonly used items from the Uniswap SDK Core. /// /// This module re-exports items that are commonly used together, /// making it easier to import them in other parts of your application. -pub mod prelude; -/// Contains utility functions and helpers used across the Uniswap SDK Core. -pub mod utils; +pub mod prelude { + pub use crate::{addresses::*, chains::*, constants::*, entities::*, error::Error, utils::*}; + + pub use alloc::{string::String, vec::Vec}; + pub use alloy_primitives::{map::rustc_hash::FxHashMap, Address, Bytes, B256, U256}; + + pub type BigInt = num_bigint::BigInt; + pub type BigUint = num_bigint::BigUint; + pub type BigDecimal = bigdecimal::BigDecimal; + pub type RoundingMode = bigdecimal::RoundingMode; +} /// Contains examples of how Uniswap sdk core can be used -pub mod examples; +#[cfg(test)] +mod examples; diff --git a/src/prelude.rs b/src/prelude.rs deleted file mode 100644 index 540b856..0000000 --- a/src/prelude.rs +++ /dev/null @@ -1,33 +0,0 @@ -pub use crate::{ - addresses::*, - chains::*, - constants::*, - entities::{ - base_currency::*, - currency::*, - ether::Ether, - fractions::{ - currency_amount::CurrencyAmount, - fraction::{Fraction, FractionBase, FractionLike, FractionTrait}, - percent::Percent, - price::Price, - }, - native_currency::NativeCurrency, - token::Token, - weth9::WETH9, - }, - error::Error, - utils::*, -}; -pub use alloc::{ - string::{String, ToString}, - vec::Vec, -}; -pub use alloy_primitives::{address, Address}; -pub use bigdecimal::{BigDecimal, RoundingMode}; -pub use core::{cmp::Ordering, num::NonZeroU64, str::FromStr}; -pub use lazy_static::lazy_static; -pub use num_bigint::{BigInt, BigUint, ToBigInt, ToBigUint}; -pub use num_integer::Integer; -pub use num_traits::{Num, ToPrimitive, Zero}; -pub use rustc_hash::FxHashMap; diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 095931c..1e01754 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -3,5 +3,10 @@ pub mod compute_zksync_create2_address; pub mod sorted_insert; pub mod sqrt; +pub use compute_price_impact::compute_price_impact; +pub use compute_zksync_create2_address::compute_zksync_create2_address; +pub use sorted_insert::sorted_insert; +pub use sqrt::sqrt; + #[cfg(feature = "validate_parse_address")] pub mod validate_and_parse_address; diff --git a/src/utils/sorted_insert.rs b/src/utils/sorted_insert.rs index 88abe53..be165cc 100644 --- a/src/utils/sorted_insert.rs +++ b/src/utils/sorted_insert.rs @@ -1,4 +1,5 @@ -use crate::prelude::*; +use alloc::vec::Vec; +use core::cmp::Ordering; /// Given an array of items sorted by `comparator`, insert an item into its sort index and constrain /// the size to `maxSize` by removing the last item diff --git a/src/utils/sqrt.rs b/src/utils/sqrt.rs index c028ac6..1426570 100644 --- a/src/utils/sqrt.rs +++ b/src/utils/sqrt.rs @@ -1,5 +1,4 @@ use crate::prelude::*; -use num_traits::Signed; /// Computes floor(sqrt(value)) /// @@ -10,7 +9,7 @@ use num_traits::Signed; /// returns: BigInt #[inline] pub fn sqrt(value: &BigInt) -> Result { - if value.is_negative() { + if value < &BigInt::ZERO { Err(Error::Invalid("NEGATIVE")) } else { Ok(value.sqrt()) @@ -20,6 +19,7 @@ pub fn sqrt(value: &BigInt) -> Result { #[cfg(test)] mod tests { use super::*; + use core::str::FromStr; #[test] fn test_sqrt_0_1000() {