From 479265f56f42e69af557e9370c31cb570172999a Mon Sep 17 00:00:00 2001 From: ts0yu <120932697+ts0yu@users.noreply.github.com> Date: Mon, 19 Aug 2024 16:17:16 +0000 Subject: [PATCH] feat(Refactor): add additional context to pool, type conversions --- .gitmodules | 3 +++ contracts/utils/lib/v4-core | 1 + src/arena.rs | 33 ++++++++++++++++++++--- src/lib.rs | 54 +++++++++++++++++++++++++++++++++++-- 4 files changed, 85 insertions(+), 6 deletions(-) create mode 160000 contracts/utils/lib/v4-core diff --git a/.gitmodules b/.gitmodules index f852f6a..e1bf959 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "contracts/utils/lib/solmate"] path = contracts/utils/lib/solmate url = https://github.com/tranmissions11/solmate +[submodule "contracts/utils/lib/v4-core"] + path = contracts/utils/lib/v4-core + url = https://github.com/uniswap/v4-core diff --git a/contracts/utils/lib/v4-core b/contracts/utils/lib/v4-core new file mode 160000 index 0000000..799dd2c --- /dev/null +++ b/contracts/utils/lib/v4-core @@ -0,0 +1 @@ +Subproject commit 799dd2cb980319a8d3b827b6a7aa59a606634553 diff --git a/src/arena.rs b/src/arena.rs index 281f97b..d579247 100644 --- a/src/arena.rs +++ b/src/arena.rs @@ -8,7 +8,7 @@ use crate::{ engine::{arbitrageur::Arbitrageur, inspector::Inspector}, feed::Feed, strategy::Strategy, - types::{ArenaToken, LiquidExchange, PoolManager, PoolManager::PoolKey}, + types::{ArenaToken, Fetcher, LiquidExchange, PoolManager, PoolManager::PoolKey}, }; /// Represents an [`Arena`] that can be used to run a simulation and execute strategies. @@ -43,6 +43,8 @@ impl Arena { .await .unwrap(); + let fetcher = Fetcher::deploy(admin_provider.clone()).await.unwrap(); + let currency_0 = ArenaToken::deploy( admin_provider.clone(), String::from("Currency 0"), @@ -70,9 +72,9 @@ impl Arena { .await .unwrap(); - if *currency_1.address() < *currency_0.address() { - self.pool.currency0 = *currency_1.address(); - self.pool.currency1 = *currency_0.address(); + if *currency_1.address() > *currency_0.address() { + (self.pool.currency0, self.pool.currency1) = + (*currency_0.address(), *currency_1.address()); } pool_manager @@ -84,8 +86,19 @@ impl Arena { .call() .await .unwrap(); + // .watch() + // .await + // .unwrap(); for (idx, strategy) in self.strategies.iter_mut().enumerate() { + let id = fetcher.toId(self.pool.clone().into()).call().await.unwrap(); + + let slot = fetcher + .getSlot0(*pool_manager.address(), id.poolId) + .call() + .await + .unwrap(); + strategy.init( self.providers[&(idx + 1)].clone(), Signal::new( @@ -93,17 +106,29 @@ impl Arena { self.pool.clone(), self.feed.current_value(), None, + slot.tick, + slot.sqrtPriceX96, ), &mut self.inspector, ); } for step in 0..config.steps { + let id = fetcher.toId(self.pool.clone().into()).call().await.unwrap(); + + let slot = fetcher + .getSlot0(*pool_manager.address(), id.poolId) + .call() + .await + .unwrap(); + let signal = Signal::new( *pool_manager.address(), self.pool.clone(), self.feed.current_value(), Some(step), + slot.tick, + slot.sqrtPriceX96, ); liquid_exchange diff --git a/src/lib.rs b/src/lib.rs index 4d9d686..fafa226 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ pub mod engine; use alloy::{ network::{Ethereum, EthereumWallet}, node_bindings::{Anvil, AnvilInstance}, - primitives::{Address, Bytes}, + primitives::{Address, Bytes, U256}, providers::{ fillers::{ChainIdFiller, FillProvider, GasFiller, JoinFill, NonceFiller, WalletFiller}, Identity, RootProvider, @@ -43,6 +43,10 @@ mod types { #![allow(clippy::too_many_arguments)] use alloy_sol_macro::sol; + use crate::types::{ + Fetcher::PoolKey as FetcherPoolKey, PoolManager::PoolKey as ManagerPoolKey, + }; + sol! { #[sol(rpc)] #[derive(Debug, Default)] @@ -63,6 +67,37 @@ mod types { ArenaToken, "src/artifacts/ArenaToken.json" } + + sol! { + #[sol(rpc)] + #[derive(Debug)] + Fetcher, + "src/artifacts/Fetcher.json" + } + + impl From for ManagerPoolKey { + fn from(fetcher: FetcherPoolKey) -> Self { + ManagerPoolKey { + currency0: fetcher.currency0, + currency1: fetcher.currency1, + fee: fetcher.fee, + tickSpacing: fetcher.tickSpacing, + hooks: fetcher.hooks, + } + } + } + + impl From for FetcherPoolKey { + fn from(manager: ManagerPoolKey) -> Self { + FetcherPoolKey { + currency0: manager.currency0, + currency1: manager.currency1, + fee: manager.fee, + tickSpacing: manager.tickSpacing, + hooks: manager.hooks, + } + } + } } /// A signal that is passed to a [`Strategy`] to provide information about the current state of the pool. @@ -79,16 +114,31 @@ pub struct Signal { /// Current step of the simulation. pub step: Option, + + /// Current tick of the pool. + pub tick: i32, + + /// Current price of the pool. + pub sqrt_price_x96: U256, } impl Signal { /// Public constructor function for a new [`Signal`]. - pub fn new(manager: Address, pool: PoolKey, current_value: f64, step: Option) -> Self { + pub fn new( + manager: Address, + pool: PoolKey, + current_value: f64, + step: Option, + tick: i32, + sqrt_price_x96: U256, + ) -> Self { Self { manager, pool, current_value, step, + tick, + sqrt_price_x96, } } }