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() {