A Rust SDK for building applications on top of Uniswap V3. Migration from the TypeScript Uniswap/v3-sdk.
It is feature-complete with unit tests matching the TypeScript SDK.
-
Opinionated Rust implementation of the Uniswap V3 SDK with a focus on readability and performance
-
Usage of alloy-rs types
-
Reimplementation of the math libraries in Uniswap V3 Math In Rust based on optimizations presented in Uni V3 Lib
-
Extensive unit tests and benchmarks
-
An
extensionsfeature for additional functionalities related to Uniswap V3, including:poolmodule for creating aPoolstruct from a pool key and fetching the liquidity map within a tick range for the specified pool, using RPC clientpositionmodule for creating aPositionstruct from a token id and fetching the state and pool for all positions of the specified owner, using RPC client, etcprice_tick_conversionsmodule for converting between prices and ticksephemeral_tick_data_providermodule for fetching ticks using an ephemeral contract in a singleeth_callephemeral_tick_map_data_providerfetches ticks in a singleeth_calland creates aTickMaptick_mapprovides a way to access tick data directly from a hashmap, supposedly more efficient thanTickList
Expand to see the benchmarks
| Function | Time | Reference |
|---|---|---|
| get_sqrt_ratio_at_tick | 4.0437 µs | 8.8094 µs |
| get_tick_at_sqrt_ratio | 21.232 µs | 31.547 µs |
| get_amount_0_delta | 3.6099 µs | 4.4475 µs |
| get_amount_1_delta | 2.5942 µs | 3.5725 µs |
Add the following to your Cargo.toml file:
uniswap-v3-sdk = { version = "4.0.0", features = ["extensions", "std"] }The package structure follows that of the TypeScript SDK, but with snake_case instead of camelCase.
For easy import, use the prelude:
use uniswap_v3_sdk::prelude::*;By default, this library does not depend on the standard library (std). However, the std feature can be enabled.
The code below shows an example of creating a pool with a tick map data provider and simulating a swap with it.
let pool = Pool::<EphemeralTickMapDataProvider>::from_pool_key_with_tick_data_provider(
1,
FACTORY_ADDRESS,
wbtc.address(),
weth.address(),
FeeAmount::LOW,
provider.clone(),
block_id,
)
.await
.unwrap();
// Get the output amount from the pool
let amount_in = CurrencyAmount::from_raw_amount(wbtc.clone(), 100000000).unwrap();
let amount_out = pool.get_output_amount(&amount_in, None).unwrap();For runnable examples, see the examples directory.
Contributions are welcome. Please open an issue if you have any questions or suggestions.
Tests are run with
cargo testfor the core library. To run the tests for the extensions, use
cargo test --all-features --lib extensions -- --test-threads=1To test a specific module, use cargo test --test <module_name>.
Linting is done with clippy and rustfmt. To run the linter, use
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --all -- --checkBenchmarking is done with criterion. To run all the benchmarks, use
cargo benchTo run a specific benchmark, use cargo bench --bench <bench_name>.
This project is licensed under the MIT License.
This project is inspired by and adapted from the following projects: