Skip to content

Commit

Permalink
Merge pull request #2 from Aperture-Finance/Flower
Browse files Browse the repository at this point in the history
Test all lens callers
  • Loading branch information
shuhuiluo committed Dec 18, 2023
2 parents 315bc47 + be4e041 commit 4ae94f2
Show file tree
Hide file tree
Showing 8 changed files with 3,528 additions and 3,289 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "aperture-lens"
version = "0.1.4"
version = "0.2.0"
edition = "2021"
license = "Apache-2.0"
repository = "https://github.com/Aperture-Finance/Aperture-Lens"
Expand All @@ -11,4 +11,4 @@ dotenv = "0.15.0"
ethers = { version = "2.0.10", features = ["default"] }
futures = "0.3.29"
serde = { version = "1.0.192", features = ["derive"] }
tokio = { version = "1.34.0", features = ["full"] }
tokio = { version = "1.35.0", features = ["full"] }
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "aperture-lens",
"version": "0.1.5",
"version": "0.2.0",
"description": "Contains ephemeral lens contracts that can be called without deployment and their interfaces in various Web3 libraries.",
"author": "Aperture Finance <engineering@aperture.finance>",
"license": "Apache-2.0",
Expand Down Expand Up @@ -39,7 +39,7 @@
"clean": "tsc --build --clean && forge clean",
"compile": "forge build",
"test": "forge test",
"test:hardhat": "npx hardhat test",
"test:hardhat": "hardhat test",
"snapshot": "forge snapshot",
"snapshot:diff": "forge snapshot --diff",
"prettier": "prettier -c {contracts,test}/**/*.sol ./**/*.ts",
Expand All @@ -50,10 +50,10 @@
"@aperture_finance/uni-v3-lib": "^1.2.0",
"@openzeppelin/contracts": "^5.0.1",
"ethers": "5.7.2",
"viem": "^1.20.0"
"viem": "^1.20.1"
},
"devDependencies": {
"@aperture_finance/uniswap-v3-automation-sdk": "^1.8.5",
"@aperture_finance/uniswap-v3-automation-sdk": "^1.9.1",
"@ethersproject/abi": "5.7.0",
"@ethersproject/providers": "5.7.2",
"@nomicfoundation/hardhat-foundry": "^1.1.1",
Expand All @@ -62,13 +62,13 @@
"@typechain/hardhat": "^7.0.0",
"@types/chai": "^4.3.11",
"@types/mocha": "^10.0.6",
"@types/node": "^20.10.0",
"@types/node": "^20.10.4",
"chai": "^4.3.10",
"hardhat": "^2.19.1",
"hardhat": "^2.19.2",
"mocha": "^10.2.0",
"prettier": "^3.1.0",
"prettier": "^3.1.1",
"prettier-plugin-solidity": "^1.2.0",
"ts-node": "^10.9.1",
"ts-node": "^10.9.2",
"typechain": "^8.3.2",
"typescript": "^5.3.3"
},
Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
pub mod bindings;
pub mod caller;
pub mod pool_lens;
pub mod position_lens;

pub mod prelude {
pub use super::{bindings::*, pool_lens::*, position_lens::*};
}

extern crate self as aperture_lens;
129 changes: 68 additions & 61 deletions src/pool_lens.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use crate::{
bindings::{
ephemeral_all_positions_by_owner::{AllPositionsReturn, EphemeralAllPositionsByOwner},
ephemeral_get_populated_ticks_in_range::{
EphemeralGetPopulatedTicksInRange, GetPopulatedTicksInRangeReturn, PopulatedTick,
},
ephemeral_get_position::{EphemeralGetPosition, GetPositionReturn, PositionState},
ephemeral_get_positions::{EphemeralGetPositions, GetPositionsReturn},
ephemeral_pool_positions::{EphemeralPoolPositions, PositionKey},
ephemeral_pool_slots::{EphemeralPoolSlots, GetSlotsReturn, Slot},
ephemeral_pool_tick_bitmap::EphemeralPoolTickBitmap,
Expand Down Expand Up @@ -35,60 +32,6 @@ pub async fn get_populated_ticks_in_range<M: Middleware>(
}
}

pub async fn get_position_details<M: Middleware>(
npm: Address,
token_id: U256,
client: Arc<M>,
block_id: Option<BlockId>,
) -> Result<PositionState, ContractError<M>> {
match call_ephemeral_contract!(
EphemeralGetPosition<M>,
(npm, token_id),
GetPositionReturn,
client,
block_id
) {
Ok(GetPositionReturn { state }) => Ok(state),
Err(err) => Err(err),
}
}

pub async fn get_positions<M: Middleware>(
npm: Address,
token_ids: U256,
client: Arc<M>,
block_id: Option<BlockId>,
) -> Result<Vec<PositionState>, ContractError<M>> {
match call_ephemeral_contract!(
EphemeralGetPositions<M>,
(npm, token_ids),
GetPositionsReturn,
client,
block_id
) {
Ok(GetPositionsReturn { positions }) => Ok(positions),
Err(err) => Err(err),
}
}

pub async fn get_all_positions_by_owner<M: Middleware>(
npm: Address,
owner: Address,
client: Arc<M>,
block_id: Option<BlockId>,
) -> Result<Vec<PositionState>, ContractError<M>> {
match call_ephemeral_contract!(
EphemeralAllPositionsByOwner<M>,
(npm, owner),
AllPositionsReturn,
client,
block_id
) {
Ok(AllPositionsReturn { positions }) => Ok(positions),
Err(err) => Err(err),
}
}

/// Call an ephemeral contract and return the decoded storage slots
macro_rules! get_pool_storage {
($contract:ty, $constructor_args:expr, $client:expr, $block_id:expr) => {
Expand Down Expand Up @@ -135,11 +78,10 @@ pub async fn get_positions_slots<M: Middleware>(
#[cfg(test)]
mod tests {
use super::*;
use crate::bindings::i_uniswap_v3_pool::{IUniswapV3Pool, MintFilter};
use anyhow::Result;
use dotenv::dotenv;
use ethers::contract::Lazy;
use futures::future::join_all;
use std::sync::Arc;

const POOL_ADDRESS: &str = "0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640";
static BLOCK_NUMBER: Lazy<BlockId> = Lazy::new(|| BlockId::from(17000000));
Expand All @@ -155,7 +97,47 @@ mod tests {
Arc::new(Provider::<Http>::connect(&*RPC_URL).await)
}

#[tokio::test]
async fn test_get_populated_ticks_in_range() -> Result<()> {
let client = make_provider().await;
let pool = IUniswapV3Pool::new(POOL_ADDRESS.parse::<Address>()?, client.clone());
let (_, tick_current, _, _, _, _, _) = pool.slot_0().block(BlockId::from(*BLOCK_NUMBER)).call().await?;
let ticks = get_populated_ticks_in_range(
POOL_ADDRESS.parse()?,
tick_current,
tick_current,
client.clone(),
Some(*BLOCK_NUMBER),
)
.await?;
assert!(!ticks.is_empty());
let mut multicall = Multicall::new(client.clone(), None).await?;
multicall.add_calls(false, ticks.iter().map(|&PopulatedTick { tick, .. }| pool.ticks(tick)));
let alt_ticks: Vec<(u128, i128, U256, U256, i64, U256, u32, bool)> = multicall
.block(match *BLOCK_NUMBER {
BlockId::Number(n) => n,
_ => panic!("block id must be a number"),
})
.call_array()
.await?;
for (
i,
&PopulatedTick {
liquidity_gross,
liquidity_net,
..
},
) in ticks.iter().enumerate()
{
let (_liquidity_gross, _liquidity_net, _, _, _, _, _, _) = alt_ticks[i];
assert_eq!(liquidity_gross, _liquidity_gross);
assert_eq!(liquidity_net, _liquidity_net);
}
Ok(())
}

async fn verify_slots(slots: Vec<Slot>, client: Arc<Provider<Http>>) {
assert!(!slots.is_empty());
let client = client.as_ref();
let futures = slots[0..4].iter().map(|slot| async move {
let data = client
Expand Down Expand Up @@ -198,6 +180,31 @@ mod tests {
Ok(())
}

// #[tokio::test]
// async fn test_get_positions_slots() -> Result<()> {}
#[tokio::test]
async fn test_get_positions_slots() -> Result<()> {
let client = make_provider().await;
let filter = MintFilter::new::<&Provider<Http>, Provider<Http>>(
Filter::new().from_block(17000000 - 10000).to_block(17000000),
&client,
);
let logs = filter.query().await?;
let positions = logs
.iter()
.map(
|&MintFilter {
owner,
tick_lower,
tick_upper,
..
}| PositionKey {
owner,
tick_lower,
tick_upper,
},
)
.collect();
let slots = get_positions_slots(POOL_ADDRESS.parse()?, positions, client.clone(), Some(*BLOCK_NUMBER)).await?;
verify_slots(slots, client).await;
Ok(())
}
}
Loading

0 comments on commit 4ae94f2

Please sign in to comment.