Uniswap V3 SDK for Rust

repository·master·Indexed 41 days ago

https://github.com/shuhuiluo/uniswap-v3-sdk-rs

A high-performance Rust implementation of the Uniswap V3 SDK (v7.0.0) for building DeFi applications. It provides core abstractions like Pool, Position, Route, and Trade, and is designed for compatibility with the original TypeScript SDK. The SDK includes various TickDataProvider implementations (Simple, Ephemeral, and EphemeralTickMap) for efficient price and liquidity calculations, and supports both std and no_std environments.

Tokens
17.8K
Snippets
58
Records
73
Agent score
50%

What's inside Uniswap V3 SDK for Rust

  1. How Tick Data Providers work

    master

    The SDK provides different implementations of TickDataProvider to fetch pool tick data, which is essential for accurate price and liquidity calculations:

    • SimpleTickDataProvider: Fetches tick data directly via standard RPC calls.
    • EphemeralTickDataProvider: Uses an ephemeral contract to fetch ticks within a single eth_call, optimizing for speed.
    • EphemeralTickMapDataProvider: Fetches ticks and constructs a TickMap to allow for highly efficient local access to tick data.
  2. Common SDK Usage Patterns

    master

    Follow these conventions when integrating the SDK into your Rust project:

    • Imports: Use uniswap_v3_sdk::prelude::* for a convenient way to import necessary types and traits.
    • Provider Setup:
      • Use setup_http_provider() for read-only operations (fetching data).
      • Use setup_anvil_fork_provider() when you need to execute transactions in a local forked environment.
    • Token Handling: The SDK handles both WETH and standard ERC20 tokens. Note that amounts should typically be expressed in their smallest unit (e.g., wei).
    • Safety: Always define a slippage tolerance (commonly between 0.5% and 1%) and a transaction deadline.
  3. Core Uniswap V3 SDK Abstractions

    master

    When building with the SDK, you will interact with these primary abstractions:

    • Pool: Represents a Uniswap V3 liquidity pool, containing its current price and liquidity state.
    • Position: Represents a specific liquidity position within a defined tick range.
    • Route: Defines the path a swap takes through one or more pools.
    • Trade: Encapsulates the details of a swap execution, including slippage tolerance settings.
  4. Understand the extensions feature

    master

    The extensions feature provides additional high-level modules for interacting with Uniswap V3 via RPC providers. Key modules include:

    • pool: Create a Pool struct from a pool key and fetch liquidity maps within a tick range.
    • position: Create a Position struct from a token ID and fetch state/pools for an owner's positions.
    • price_tick_conversions: Convert between prices and ticks.
    • simple_tick_data_provider: Fetch tick data directly from a pool contract via RPC.
    • ephemeral_tick_data_provider: Fetch ticks using an ephemeral contract in a single eth_call.
    • ephemeral_tick_map_data_provider: Fetches ticks in a single eth_call and creates a TickMap.
    • tick_map: Provides efficient access to tick data via a hashmap.
  5. Setup the Uniswap V3 SDK Examples environment

    master

    To run the examples, you must meet the following prerequisites and configuration steps:

    Prerequisites

    • Rust Version: 1.88 or later
    • RPC URL: A valid Ethereum mainnet RPC URL for forking.

    Configuration

    1. Create a .env file in the project root and add your RPC URL:

      MAINNET_RPC_URL=https://your-ethereum-mainnet-rpc-url
    2. Build the project with the extensions feature enabled, which is required for RPC-based functionality like pool creation and tick data providers:

      cargo build --features extensions
    cargo build --features extensions
  6. Install the uniswap-v3-sdk crate

    master

    To use the Uniswap V3 SDK in your Rust project, add it to your Cargo.toml. It is recommended to enable the extensions and std features for full functionality, including RPC-based data providers and standard library support.

    uniswap-v3-sdk = { version = "7.0.0", features = ["extensions", "std"] }
  7. Standard Transaction Building Workflow

    master

    To execute a transaction using the SDK, follow this general pattern:

    1. Initialize Pool: Create or load a Pool instance with the target token pair and fee tier.
    2. Calculate Amounts: Determine swap amounts using either local simulation or the Uniswap V3 Quoter contract.
    3. Build Parameters: Construct transaction parameters, ensuring you include appropriate slippage tolerance and a deadline.
    4. Execute: Send the transaction through the relevant Uniswap V3 contract (e.g., SwapRouter or NonfungiblePositionManager).
  8. Run Uniswap V3 SDK Examples

    master

    Each example in the repository can be executed independently using cargo run. You must include the --features extensions flag for these examples to function correctly.

    Available Examples

    • Pool and Quoter Comparison: from_pool_key_with_tick_data_provider (compares local simulation vs. quoter contract).
    • Swap Router: swap_router (executes exact input/output swaps with slippage protection).
    • Position Manager: nonfungible_position_manager (manages liquidity positions as NFTs).
    • Self Permit: self_permit (signs ERC20 permits for gasless approvals).
    # Run the pool creation and quoter comparison example
    cargo run --example from_pool_key_with_tick_data_provider --features extensions
    
    # Run the swap router example
    cargo run --example swap_router --features extensions
    
    # Run the position manager example
    cargo run --example nonfungible_position_manager --features extensions
    
    # Run the self permit example
    cargo run --example self_permit --features extensions
  9. How Pool and TickDataProvider work together

    master

    The Pool<TP> struct is generic over a TickDataProvider (TP).

    1. Static Pools: If you only need to access pool metadata (address, tokens, fee) or calculate prices based on current sqrt_ratio_x96, you can use Pool::new which uses NoTickDataProvider. This does not require async and is very lightweight.
    2. Dynamic/Simulated Pools: If you need to perform swap simulations (get_output_amount, etc.), you must use Pool::new_with_tick_data_provider. The TickDataProvider provides the necessary tick data to the swap algorithm to account for liquidity changes across different price ranges.
    3. Transitioning: You can convert a pool with one provider to another using .with_tick_data_provider(new_provider).
  10. Understand how `trade_comparator` ranks trades

    master

    The trade_comparator function is used to sort trades to find the 'best' ones. It uses the following logic hierarchy:

    1. Output Amount: Trades with higher output amounts are ranked higher (preferred).
    2. Input Amount: If output amounts are equal, trades requiring less input are ranked higher (preferred).
    3. Hops: If both output and input amounts are equal, trades with fewer hops (fewer pools in the route) are ranked higher to minimize gas costs.