Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add example and documentation for pool creation with tick data #110

Merged
merged 4 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ harness = false
[[bench]]
name = "tick_math"
harness = false

[[example]]
name = "from_pool_key_with_tick_data_provider"
required-features = ["extensions"]
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,33 @@ use uniswap_v3_sdk::prelude::*;
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.

## Examples

The code below shows an example of creating a pool with a tick map data provider and simulating a swap with it.

```rust
#[tokio::main]
async fn main() {
// Create a pool with a tick map data provider
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_after) = pool.get_output_amount(&amount_in, None).unwrap();
}
```

For runnable examples, see the [examples](./examples) directory.

## Contributing

Contributions are welcome. Please open an issue if you have any questions or suggestions.
Expand Down
69 changes: 69 additions & 0 deletions examples/from_pool_key_with_tick_data_provider.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//! Example demonstrating pool creation with tick data provider and swap simulation
//!
//! # Prerequisites
//! - Environment variable MAINNET_RPC_URL must be set
//! - Requires the "extensions" feature
//!
//! # Note
//! This example uses mainnet block 17000000 for consistent results

use alloy::{
eips::BlockId,
providers::{Provider, ProviderBuilder},
rpc::types::TransactionRequest,
};
use alloy_primitives::{address, ruint::aliases::U256, U160};
use alloy_sol_types::SolValue;
use uniswap_sdk_core::{prelude::*, token};
use uniswap_v3_sdk::prelude::*;

#[tokio::main]
async fn main() {
dotenv::dotenv().ok();
let rpc_url = std::env::var("MAINNET_RPC_URL").unwrap().parse().unwrap();
let provider = ProviderBuilder::new().on_http(rpc_url);
let block_id = BlockId::from(17000000);
shuhuiluo marked this conversation as resolved.
Show resolved Hide resolved
shuhuiluo marked this conversation as resolved.
Show resolved Hide resolved
let wbtc = token!(1, "2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599", 8, "WBTC");
let weth = token!(1, "C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 18, "WETH");

// Create a pool with a tick map data provider
let pool = Pool::<EphemeralTickMapDataProvider>::from_pool_key_with_tick_data_provider(
1,
FACTORY_ADDRESS,
wbtc.address(),
weth.address(),
FeeAmount::LOW,
provider.clone(),
Some(block_id),
)
.await
.unwrap();
// Get the output amount from the pool
let amount_in = CurrencyAmount::from_raw_amount(wbtc.clone(), 100000000).unwrap();
let (local_amount_out, _pool_after) = pool.get_output_amount(&amount_in, None).unwrap();
println!("Local amount out: {}", local_amount_out.quotient());

let route = Route::new(vec![pool.clone()], wbtc, weth);
let params = quote_call_parameters(
&route,
&amount_in,
TradeType::ExactInput,
Some(QuoteOptions {
sqrt_price_limit_x96: U160::ZERO,
use_quoter_v2: false,
}),
);
let quoter_addr = *QUOTER_ADDRESSES.get(&1).unwrap();
let tx = TransactionRequest {
to: Some(quoter_addr.into()),
input: params.calldata.into(),
..Default::default()
};
// Get the output amount from the quoter
let res = provider.call(&tx).block(block_id).await.unwrap();
let amount_out = U256::abi_decode(res.as_ref(), true).unwrap();
println!("Quoter amount out: {}", amount_out);

// Compare local calculation with on-chain quoter to ensure accuracy
assert_eq!(U256::from_big_int(local_amount_out.quotient()), amount_out);
}
42 changes: 42 additions & 0 deletions src/extensions/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,48 @@ impl Pool {
}

impl<I: TickIndex> Pool<EphemeralTickMapDataProvider<I>> {
/// Get a [`Pool`] struct with tick data provider from pool key
///
/// ## Arguments
///
/// * `chain_id`: The chain id
/// * `factory`: The factory address
/// * `token_a`: One of the tokens in the pool
/// * `token_b`: The other token in the pool
/// * `fee`: Fee tier of the pool
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query.
///
/// ## Returns
///
/// A [`Pool`] struct with tick data provider
///
/// ## Examples
///
/// ```
/// use alloy::{eips::BlockId, providers::ProviderBuilder};
/// use alloy_primitives::address;
/// use uniswap_v3_sdk::prelude::*;
///
/// #[tokio::main]
/// async fn main() {
/// dotenv::dotenv().ok();
/// let rpc_url = std::env::var("MAINNET_RPC_URL").unwrap().parse().unwrap();
/// let provider = ProviderBuilder::new().on_http(rpc_url);
/// let block_id = Some(BlockId::from(17000000));
/// let pool = Pool::<EphemeralTickMapDataProvider>::from_pool_key_with_tick_data_provider(
/// 1,
/// FACTORY_ADDRESS,
/// address!("2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"),
/// address!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
/// FeeAmount::LOW,
/// provider,
/// block_id,
/// )
/// .await
/// .unwrap();
/// }
/// ```
#[inline]
pub async fn from_pool_key_with_tick_data_provider<T, P>(
chain_id: ChainId,
Expand Down
Loading