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

feat(alloy): update alloy to 0.3 #6

Merged
merged 4 commits into from
Sep 1, 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
39 changes: 13 additions & 26 deletions .gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,26 +1,13 @@
PCSV3PoolLensTest:testFuzz_GetPositions(int24,int24) (runs: 17, μ: 1392200, ~: 1437447)
PCSV3PoolLensTest:test_GetPopulatedTicksInRange() (gas: 524480)
PCSV3PoolLensTest:test_GetPositions() (gas: 1348279)
PCSV3PoolLensTest:test_GetSlots() (gas: 151189)
PCSV3PoolLensTest:test_GetTickBitmap() (gas: 3370484)
PCSV3PositionLensTest:testFuzz_GetPosition(uint256) (runs: 17, μ: 274996, ~: 275218)
PCSV3PositionLensTest:test_AllPositions() (gas: 19719373)
PCSV3PositionLensTest:test_GetFeesOwed() (gas: 2791103)
PCSV3PositionLensTest:test_GetPositions() (gas: 1176049)
PCSV3PositionLensTest:test_GetTotalAmounts() (gas: 2794460)
PCSV3StorageLensTest:testFuzz_extsload(bytes32) (runs: 257, μ: 33810, ~: 33944)
PCSV3StorageLensTest:test_extsload() (gas: 66675)
PCSV3TickLensTest:test_GetPopulatedTicksInRange() (gas: 793601)
PoolLensTest:testFuzz_GetPositions(int24,int24) (runs: 17, μ: 1389477, ~: 1419421)
PoolLensTest:test_GetPopulatedTicksInRange() (gas: 4524074)
PoolLensTest:test_GetPositions() (gas: 1132031)
PoolLensTest:test_GetSlots() (gas: 3695636)
PoolLensTest:test_GetTickBitmap() (gas: 3385051)
PositionLensTest:testFuzz_GetPosition(uint256) (runs: 17, μ: 271318, ~: 272509)
PositionLensTest:test_AllPositions() (gas: 1137940)
PositionLensTest:test_GetFeesOwed() (gas: 2444915)
PositionLensTest:test_GetPositions() (gas: 940131)
PositionLensTest:test_GetTotalAmounts() (gas: 2456667)
StorageLensTest:testFuzz_extsload(bytes32) (runs: 17, μ: 33820, ~: 33944)
StorageLensTest:test_extsload() (gas: 66675)
TickLensTest:test_GetPopulatedTicksInRange() (gas: 11472791)
PoolLensTest:testFuzz_GetPositions(int24,int24) (runs: 22, μ: 1364083, ~: 1404255)
PoolLensTest:test_GetPopulatedTicksInRange() (gas: 4544800)
PoolLensTest:test_GetPositions() (gas: 1132120)
PoolLensTest:test_GetSlots() (gas: 3710586)
PoolLensTest:test_GetTickBitmap() (gas: 3399608)
PositionLensTest:testFuzz_GetPosition(uint256) (runs: 22, μ: 270296, ~: 272574)
PositionLensTest:test_AllPositions() (gas: 1140527)
PositionLensTest:test_GetFeesOwed() (gas: 2444865)
PositionLensTest:test_GetPositions() (gas: 940419)
PositionLensTest:test_GetTotalAmounts() (gas: 2456617)
StorageLensTest:testFuzz_extsload(bytes32) (runs: 22, μ: 33735, ~: 33755)
StorageLensTest:test_extsload() (gas: 66705)
TickLensTest:test_GetPopulatedTicksInRange() (gas: 11486985)
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
[package]
name = "uniswap-lens"
version = "0.1.0"
version = "0.2.0"
edition = "2021"
authors = ["Shuhui Luo <twitter.com/aureliano_law>"]
description = "Contains ephemeral lens contracts that can be called without deployment and their Rust interfaces."
description = "A library for querying Uniswap V3 using ephemeral lens contracts."
license = "Apache-2.0"
readme = "README.md"
repository = "https://github.com/shuhuiluo/uniswap-lens-rs"
keywords = ["alloy", "ethereum", "solidity", "rust", "uniswap"]
keywords = ["alloy", "ethereum", "solidity", "uniswap"]
include = ["src/**/*.rs"]

[dependencies]
alloy = { version = "0.2.0", features = ["contract", "rpc-types", "transports"] }
alloy = { version = "0.3.0", features = ["contract", "rpc-types", "transports"] }
anyhow = "1"

[dev-dependencies]
alloy = { version = "0.2.0", features = ["transport-http"] }
alloy = { version = "0.3.0", features = ["transport-http"] }
dotenv = "0.15.0"
futures = "0.3"
once_cell = "1.19"
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@
[![npm version](https://img.shields.io/npm/v/aperture-lens/latest.svg)](https://www.npmjs.com/package/aperture-lens/v/latest)
[![crates.io](https://img.shields.io/crates/v/uniswap-lens.svg)](https://crates.io/crates/uniswap-lens)

Contains ephemeral lens contracts that can be called without deployment and their interfaces in various Web3 libraries.
A library for querying Uniswap V3 using ephemeral lens contracts.

## Features

- Lens contracts in Solidity using the revert-in-constructor pattern
- Rust SDK for querying lens contracts using [alloy-rs](https://github.com/alloy-rs)
- TypeScript SDK for querying lens contracts using viem
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,6 @@
],
"endOfLine": "lf",
"printWidth": 120
}
},
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
//! # uniswap-lens
//!
//! A library for querying Uniswap V3 using ephemeral lens contracts.
#![warn(
missing_copy_implementations,
missing_debug_implementations,
unreachable_pub,
clippy::missing_const_for_fn,
clippy::redundant_clone,
rustdoc::all
)]
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
Expand Down
82 changes: 75 additions & 7 deletions src/pool_lens.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! ## Pool Lens
//!
//! The pool lens module provides functions to fetch pool details using ephemeral contracts.

use crate::{
bindings::{
ephemeralgetpopulatedticksinrange::EphemeralGetPopulatedTicksInRange::{
Expand All @@ -18,17 +22,30 @@ use crate::{
use alloy::{
contract::Error,
eips::BlockId,
primitives::{Address, Bytes},
primitives::{aliases::I24, Address, Bytes},
providers::Provider,
sol_types::SolCall,
transports::{Transport, TransportError},
};
use anyhow::Result;

/// Get the populated ticks in a tick range.
///
/// ## Arguments
///
/// * `pool`: The address of a V3 pool
/// * `tick_lower`: The lower tick boundary
/// * `tick_upper`: The upper tick boundary
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query
///
/// ## Returns
///
/// A vector of populated ticks within the range
pub async fn get_populated_ticks_in_range<T, P>(
pool: Address,
tick_lower: i32,
tick_upper: i32,
tick_lower: I24,
tick_upper: I24,
provider: P,
block_id: Option<BlockId>,
) -> Result<Vec<PopulatedTick>>
Expand All @@ -40,7 +57,10 @@ where
provider, pool, tick_lower, tick_upper,
);
match call_ephemeral_contract!(deploy_builder, getPopulatedTicksInRangeCall, block_id) {
Ok(getPopulatedTicksInRangeReturn { populatedTicks }) => Ok(populatedTicks),
Ok(getPopulatedTicksInRangeReturn { populatedTicks }) => Ok(populatedTicks
.into_iter()
.filter(|PopulatedTick { tick, .. }| *tick >= tick_lower && *tick <= tick_upper)
.collect()),
Err(err) => Err(err.into()),
}
}
Expand All @@ -55,6 +75,17 @@ macro_rules! get_pool_storage {
};
}

/// Get the static storage slots of a pool.
///
/// ## Arguments
///
/// * `pool`: The address of a V3 pool
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query
///
/// ## Returns
///
/// A vector of slots containing the storage data
pub async fn get_static_slots<T, P>(
pool: Address,
provider: P,
Expand All @@ -70,10 +101,23 @@ where
)
}

/// Get the storage slots in the `ticks` mapping between `tick_lower` and `tick_upper`.
///
/// ## Arguments
///
/// * `pool`: The address of a V3 pool
/// * `tick_lower`: The lower tick boundary
/// * `tick_upper`: The upper tick boundary
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query
///
/// ## Returns
///
/// A vector of slots containing the storage data
pub async fn get_ticks_slots<T, P>(
pool: Address,
tick_lower: i32,
tick_upper: i32,
tick_lower: I24,
tick_upper: I24,
provider: P,
block_id: Option<BlockId>,
) -> Result<Vec<Slot>>
Expand All @@ -86,6 +130,17 @@ where
block_id
)
}
/// Get the storage slots in the `tickBitmap` mapping.
///
/// ## Arguments
///
/// * `pool`: The address of a V3 pool
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query
///
/// ## Returns
///
/// A vector of slots containing the storage data
pub async fn get_tick_bitmap_slots<T, P>(
pool: Address,
provider: P,
Expand All @@ -100,6 +155,18 @@ where
block_id
)
}
/// Get the storage slots in the `positions` mapping.
///
/// ## Arguments
///
/// * `pool`: The address of a V3 pool
/// * `positions`: A vector of position keys
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query
///
/// ## Returns
///
/// A vector of slots containing the storage data
pub async fn get_positions_slots<T, P>(
pool: Address,
positions: Vec<PositionKey>,
Expand Down Expand Up @@ -133,10 +200,11 @@ mod tests {
let provider = PROVIDER.clone();
let pool = IUniswapV3PoolInstance::new(POOL_ADDRESS, provider.clone());
let tick_current = pool.slot0().block(*BLOCK_NUMBER).call().await?.tick;
let tick_spacing = pool.tickSpacing().block(*BLOCK_NUMBER).call().await?._0;
let ticks = get_populated_ticks_in_range(
POOL_ADDRESS,
tick_current,
tick_current,
tick_current + (tick_spacing << 8),
provider,
Some(*BLOCK_NUMBER),
)
Expand Down
46 changes: 43 additions & 3 deletions src/position_lens.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! ## Position Lens
//!
//! The position lens module provides functions to fetch position details using ephemeral contracts.

use crate::{
bindings::{
ephemeralallpositionsbyowner::{
Expand Down Expand Up @@ -31,6 +35,18 @@ use alloy::{
};
use anyhow::Result;

/// Get the details of a position given the token ID.
///
/// ## Arguments
///
/// * `npm`: The address of the non-fungible position manager
/// * `token_id`: The token ID of the position
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query
///
/// ## Returns
///
/// The position details
pub async fn get_position_details<T, P>(
npm: Address,
token_id: U256,
Expand All @@ -48,6 +64,18 @@ where
}
}

/// Get the details of multiple positions given the token IDs.
///
/// ## Arguments
///
/// * `npm`: The address of the non-fungible position manager
/// * `token_ids`: The token IDs of the positions
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query
///
/// ## Returns
///
/// The array of position details
pub async fn get_positions<T, P>(
npm: Address,
token_ids: Vec<U256>,
Expand All @@ -65,6 +93,18 @@ where
}
}

/// Get all positions owned by an address.
///
/// ## Arguments
///
/// * `npm`: The address of the non-fungible position manager
/// * `owner`: The address of the owner
/// * `provider`: The alloy provider
/// * `block_id`: Optional block number to query
///
/// ## Returns
///
/// The array of position details
pub async fn get_all_positions_by_owner<T, P>(
npm: Address,
owner: Address,
Expand Down Expand Up @@ -94,7 +134,7 @@ mod tests {
tests::*,
};
use alloy::{
primitives::{address, b256, keccak256, uint, B256},
primitives::{address, aliases::U24, b256, keccak256, uint, B256},
sol_types::SolValue,
};

Expand All @@ -119,15 +159,15 @@ mod tests {
factory: Address,
token_a: Address,
token_b: Address,
fee: u32,
fee: U24,
init_code_hash: B256,
) -> Address {
let (token_0, token_1) = if token_a < token_b {
(token_a, token_b)
} else {
(token_b, token_a)
};
let pool_key = (token_0, token_1, fee as i32);
let pool_key = (token_0, token_1, fee);
factory.create2(keccak256(pool_key.abi_encode()), init_code_hash)
}

Expand Down
5 changes: 5 additions & 0 deletions src/storage_lens.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! ## Storage Lens
//!
//! The storage lens module provides a function to batch `eth_getStorageAt` RPC calls in a single
//! `eth_call` by overriding the target contract's deployed bytecode with `EphemeralStorageLens`.

use crate::bindings::ephemeralstoragelens::{
EphemeralStorageLens, EphemeralStorageLens::EphemeralStorageLensInstance,
};
Expand Down
Loading
Loading