Opinionated Rust implementation of the Uniswap V3 SDK with a focus on readability and performance
Uniswap V3 SDK Rust
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.
Features
- 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
- Extensive unit tests and benchmarks
- An
extensionsfeature for additional functionalities related to Uniswap V3, including:
pool module for creating a Pool struct from a pool key and fetching the
liquidity map within a tick range for the specified pool, using an RPC provider
- position module for creating a Position struct from a token id and fetching
the state and pool for all positions of the specified owner, etc., using an RPC provider
- pricetick_conversions module for converting between prices and
ticks
- simpletickdata_provider module for fetching tick data
from a Uniswap V3 pool contract directly via RPC calls
- ephemeraltickdata_provider module for fetching ticks using
an ephemeral contract
in a single eth_call
- ephemeraltickmapdata_provider fetches ticks in a
single eth_call and creates a TickMap
- tick_map provides a way to access tick data directly from a hashmap, supposedly
more efficient than TickList
Expand to see the benchmarks
| Function | Time | Reference | |------------------------|-----------|-----------| | getsqrtratioattick | 4.0437 µs | 8.8094 µs | | gettickatsqrtratio | 21.232 µs | 31.547 µs | | getamount0_delta | 3.6099 µs | 4.4475 µs | | getamount1_delta | 2.5942 µs | 3.5725 µs |
Supported Rust Versions (MSRV)
The current MSRV (minimum supported Rust version) is 1.88.
To avoid transitive dependencies requiring a newer rustc, use edition 2024 or add to .cargo/config.toml:
[resolver]
incompatible-rust-versions = "fallback"
Getting started
Add the following to your Cargo.toml file:
uniswap-v3-sdk = { version = "6.2.0", features = ["extensions", "std"] }
Usage
The package structure follows that of the TypeScript SDK, but with snake_case instead of camelCase.
For easy import, use the prelude:
use uniswapv3sdk::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 creating a pool with a tick map data provider and simulating a swap with it.
,ignore
let pool = Pool::<EphemeralTickMapDataProvider>::frompoolkeywithtickdataprovider(
1,
FACTORY_ADDRESS,
wbtc.address(),
weth.address(),
FeeAmount::LOW,
provider.clone(),
block_id,
)
.await
.unwrap();
// Get the output amount from the pool
let amountin = CurrencyAmount::fromraw_amount(wbtc.clone(), 100000000).unwrap();
let amountout = pool.getoutputamount(&amountin, None).unwrap();
For runnable examples, see the examples directory.
Contributing
Contributions are welcome. Please open an issue if you have any questions or suggestions.
Testing
Tests are run with
cargo test
for the core library. To run the tests for the extensions, use
cargo test --all-features --lib extensions -- --test-threads=1
To test a specific module, use cargo test --test <module_name>.
Linting
Linting is done with clippy and rustfmt. To run the linter, use
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --all -- --check
Benchmarking
Benchmarking is done with criterion. To run all the benchmarks, use
cargo bench
To run a specific benchmark, use cargo bench --bench <bench_name>.
License
This project is licensed under the MIT License.
Acknowledgements
This project is inspired by and adapted from the following projects: