From 1b08a94a858186f825b77517f14bc865cd63a597 Mon Sep 17 00:00:00 2001 From: bsh98 <31482749+bsh98@users.noreply.github.com> Date: Fri, 10 Feb 2023 16:29:10 -0800 Subject: [PATCH] feat(examples): add basic event filtering example (#2137) --- CHANGELOG.md | 1 + examples/README.md | 2 +- examples/events/examples/filtering.rs | 48 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 examples/events/examples/filtering.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 5510068b..8ca82ecb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -114,6 +114,7 @@ Added `twos_complement` function for I256. - [#1934](https://github.com/gakonst/ethers-rs/pull/1934) Allow 16 calls in multicall. - [#1941](https://github.com/gakonst/ethers-rs/pull/1941) Add `add_calls` and `call_array` for `Multicall`. +- Added basic event log filtering example. ## ethers-contract-abigen diff --git a/examples/README.md b/examples/README.md index bb25a09d..c37836b0 100644 --- a/examples/README.md +++ b/examples/README.md @@ -22,7 +22,7 @@ - [x] Events with meta - [ ] Methods - [ ] Events - - [ ] Logs and filtering + - [x] Logs and filtering - [ ] Solidity topics - [ ] Middleware - [x] Builder diff --git a/examples/events/examples/filtering.rs b/examples/events/examples/filtering.rs new file mode 100644 index 00000000..5791934e --- /dev/null +++ b/examples/events/examples/filtering.rs @@ -0,0 +1,48 @@ +use ethers::{ + core::types::{Address, Filter, H160, H256, U256}, + providers::{Http, Middleware, Provider}, +}; +use eyre::Result; +use std::sync::Arc; +use tokio; + +const HTTP_URL: &str = "https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27"; +const V3FACTORY_ADDRESS: &str = "0x1F98431c8aD98523631AE4a59f267346ea31F984"; +const DAI_ADDRESS: &str = "0x6B175474E89094C44Da98b954EedeAC495271d0F"; +const USDC_ADDRESS: &str = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; +const USDT_ADDRESS: &str = "0xdAC17F958D2ee523a2206206994597C13D831ec7"; + +/// This example demonstrates filtering and parsing event logs by fetching all Uniswap V3 pools +/// where both tokens are in the set [USDC, USDT, DAI]. +/// +/// V3 factory reference: https://github.com/Uniswap/v3-core/blob/main/contracts/interfaces/IUniswapV3Factory.sol +#[tokio::main] +async fn main() -> Result<()> { + let provider = Provider::::try_from(HTTP_URL)?; + let client = Arc::new(provider); + let token_topics = vec![ + H256::from(USDC_ADDRESS.parse::()?), + H256::from(USDT_ADDRESS.parse::()?), + H256::from(DAI_ADDRESS.parse::()?), + ]; + let filter = Filter::new() + .address(V3FACTORY_ADDRESS.parse::
()?) + .event("PoolCreated(address,address,uint24,int24,address)") + .topic1(token_topics.to_vec()) + .topic2(token_topics.to_vec()) + .from_block(0); + let logs = client.get_logs(&filter).await?; + println!("{} pools found!", logs.iter().len()); + for log in logs.iter() { + let token0 = Address::from(log.topics[1]); + let token1 = Address::from(log.topics[2]); + let fee_tier = U256::from_big_endian(&log.topics[3].as_bytes()[29..32]); + let tick_spacing = U256::from_big_endian(&log.data[29..32]); + let pool = Address::from(&log.data[44..64].try_into()?); + println!( + "pool = {}, token0 = {}, token1 = {}, fee = {}, spacing = {}", + pool, token0, token1, fee_tier, tick_spacing, + ); + } + Ok(()) +}