Skip to content

Commit

Permalink
feat(alloy): update alloy to 0.3 (#6)
Browse files Browse the repository at this point in the history
* Add alias types and upgrade dependencies

Replaced primitive integer types with alias types (U24 and I24) for better clarity and consistency. Enabled `clippy::redundant_clone` lint. Updated `alloy` dependency and incremented package version to 0.2.0.

* Add detailed documentation to lens modules

Enhance the position, pool, and storage lens modules in the code with comprehensive documentation. This includes descriptions of functionalities and explanations of arguments and return values for functions. Additionally, update the README and Cargo.toml to reflect the library's purpose and features accurately.

* Fix test

* Remove PCSV3-specific tests

Deleted tests related to PancakeSwap V3 for BSC in both TypeScript and Solidity test files. This includes the removal of the PCSV3-specific PoolLens and StorageLens tests as well as updates to the gas-snapshot file to reflect these deletions.
  • Loading branch information
shuhuiluo committed Sep 1, 2024
1 parent d05c0f7 commit 073ee03
Show file tree
Hide file tree
Showing 13 changed files with 155 additions and 338 deletions.
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

0 comments on commit 073ee03

Please sign in to comment.