From f3889ef3e9df622b9ab02cddd3e2cd5ab7a47649 Mon Sep 17 00:00:00 2001 From: Colin Roberts Date: Fri, 12 Apr 2024 16:14:31 -0700 Subject: [PATCH] refactor: tests --- kit/src/behaviors/creator.rs | 49 +------ kit/src/behaviors/deployer.rs | 74 ----------- kit/src/behaviors/mod.rs | 56 +------- kit/src/behaviors/token_admin.rs | 188 +++++++++++++-------------- kit/src/lib.rs | 25 +--- kit/src/pool/constant_sum.rs | 4 +- kit/src/pool/mod.rs | 3 +- kit/tests/common.rs | 72 ++++++++++ kit/tests/creator_integration.rs | 11 ++ kit/tests/deployer.rs | 49 +++++++ kit/tests/token_admin_integration.rs | 10 ++ 11 files changed, 240 insertions(+), 301 deletions(-) create mode 100644 kit/tests/common.rs create mode 100644 kit/tests/creator_integration.rs create mode 100644 kit/tests/deployer.rs create mode 100644 kit/tests/token_admin_integration.rs diff --git a/kit/src/behaviors/creator.rs b/kit/src/behaviors/creator.rs index d6143830..ce7972fe 100644 --- a/kit/src/behaviors/creator.rs +++ b/kit/src/behaviors/creator.rs @@ -11,16 +11,7 @@ use crate::{ pool::{Pool, PoolType}, }; -// Idea: Let's make a behavior that has two states: -// State 1. This is for configuration and it should have everything be -// `Serialize`/`Deserialize` so that it can be read in from a config. -// State 2. This is the "built" version of the behavior that may now own client, -// messager, or contracts (etc.) and other things that had to be gotten from -// running the `startup` method. - -// Example: -// Let's make a "pool_creator" type of behavior that will take some -// configuration for a pool and work to attempt to deploy that pool. +pub const MAX: eU256 = eU256::MAX; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct Creator { @@ -108,7 +99,7 @@ where .await? .await?; - let pool = Pool::

::new( + let _pool = Pool::

::new( self.data.base_config.clone(), self.data.params.clone(), self.data.allocation_data.clone(), @@ -121,39 +112,3 @@ where Ok(None) } } - -mod test { - use arbiter_engine::{agent::Agent, world::World}; - use tracing::{level_filters::LevelFilter, Level}; - use tracing_subscriber::FmtSubscriber; - - use super::*; - use crate::behaviors::deployer::Deployer; - - #[tokio::test(flavor = "multi_thread", worker_threads = 5)] - async fn creator_behavior_test() { - let subscriber = FmtSubscriber::builder() - .with_max_level(Level::DEBUG) - .pretty() - .finish(); - tracing::subscriber::set_global_default(subscriber).unwrap(); - - let mut world = World::new("test"); - - // deployer - let agent = Agent::builder("deployer"); - world.add_agent(agent.with_behavior(Deployer {})); - - // Token Admin - let token_admin_config = default_admin_config(); - let token_admin = Agent::builder("token_admin_agent"); - world.add_agent(token_admin.with_behavior(token_admin_config)); - - // Pool Creator - let creator = Agent::builder("pool_creator_agent"); - let pool_creator_config = default_creator_config(); - world.add_agent(creator.with_behavior(pool_creator_config)); - - world.run().await.unwrap(); - } -} diff --git a/kit/src/behaviors/deployer.rs b/kit/src/behaviors/deployer.rs index ad0a3164..6e3b196d 100644 --- a/kit/src/behaviors/deployer.rs +++ b/kit/src/behaviors/deployer.rs @@ -72,77 +72,3 @@ impl Behavior<()> for Deployer { Ok(None) } } - -#[cfg(test)] -mod tests { - use std::str::FromStr; - - use arbiter_engine::{agent::Agent, world::World}; - use ethers::types::Address; - use futures_util::StreamExt; - use tracing_subscriber::FmtSubscriber; - - use crate::behaviors::deployer::{Deployer, DeploymentData}; - - #[tokio::test(flavor = "multi_thread", worker_threads = 4)] - async fn deployer_behavior_test() { - let subscriber = FmtSubscriber::builder().finish(); - tracing::subscriber::set_global_default(subscriber).unwrap(); - - let mut world = World::new("test"); - let messager = world.messager.clone(); - - let agent = Agent::builder("token_admin_agent"); - world.add_agent(agent.with_behavior(Deployer {})); - - world.run().await.unwrap(); - let mut stream = messager.stream().expect( - "Failed to get messager -stream", - ); - - if let Some(res) = stream.next().await { - let token_res_data = &res.data; - println!("{}", token_res_data); - - let data: String = serde_json::from_str(token_res_data).expect( - "Failed to -deserialize message data", - ); - - let parsed_data: DeploymentData = serde_json::from_str(&data).expect( - "Failed to deserialize -token data", - ); - - println!("{:?}", parsed_data); - - assert_eq!( - Address::from_str("0xb00efcb70090a21d46660adf95a16ec69623f694").unwrap(), - parsed_data.weth - ); - assert_eq!( - Address::from_str("0x27781b40bd019ccb1dcb0c809135db71222e9353").unwrap(), - parsed_data.dfmm - ); - assert_eq!( - Address::from_str("0x6e0035324097bfc66442e2d3f37ef378fb3750b2").unwrap(), - parsed_data.geometric_mean - ); - assert_eq!( - Address::from_str("0x4be050270d209ef9f0c0435736c731767486279f").unwrap(), - parsed_data.log_normal - ); - assert_eq!( - Address::from_str("0xaeb166f1355c6254d01a54317ef8d4d21bfcb4b0").unwrap(), - parsed_data.constant_sum - ); - assert_eq!( - Address::from_str("0xa4bb88cbfc92d86ae00842dcfa5a1ac32b0714b3").unwrap(), - parsed_data.n_token_geometric_mean - ); - } else { - panic!("No message received"); - } - } -} diff --git a/kit/src/behaviors/mod.rs b/kit/src/behaviors/mod.rs index d67d3842..932689e8 100644 --- a/kit/src/behaviors/mod.rs +++ b/kit/src/behaviors/mod.rs @@ -7,16 +7,10 @@ use arbiter_engine::{ use arbiter_macros::Behaviors; use bindings::arbiter_token::ArbiterToken; -use self::{ - creator::Creator, - deployer::Deployer, - pool::{ - constant_sum::{ConstantSumAllocationData, ConstantSumParams, ConstantSumPool}, - BaseConfig, PoolType, - }, - token_admin::TokenAdmin, -}; +use self::{creator::Creator, deployer::Deployer, pool::PoolType, token_admin::TokenAdmin}; + use super::*; +pub use token_admin::{MintRequest, TokenAdminQuery}; // pub mod allocate; pub mod creator; @@ -29,47 +23,3 @@ pub enum Behaviors { Deployer(Deployer), TokenAdmin(TokenAdmin), } - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct TokenData { - pub name: String, - pub symbol: String, - pub decimals: u8, -} - -pub(crate) fn default_admin_config() -> TokenAdmin { - let token1 = TokenData { - name: "US Dollar Coin".to_owned(), - symbol: "USDC".to_owned(), - decimals: 18, - }; - - let token2 = TokenData { - name: "ShibaInuObamaSonic Coin".to_owned(), - symbol: "SIOS".to_owned(), - decimals: 18, - }; - let config = token_admin::Config { - token_data: vec![token1, token2], - }; - TokenAdmin:: { data: config } -} - -pub(crate) fn default_creator_config() -> Creator> { - Creator::> { - data: creator::Config { - params: ConstantSumParams { price: WAD }, - token_list: vec!["Token X".to_string(), "Token Y".to_string()], - base_config: BaseConfig { - name: "Test Pool".to_string(), - symbol: "TP".to_string(), - swap_fee: 10000.into(), - controller_fee: 0.into(), - }, - allocation_data: ConstantSumAllocationData { - reserve_x: WAD, - reserve_y: WAD, - }, - }, - } -} diff --git a/kit/src/behaviors/token_admin.rs b/kit/src/behaviors/token_admin.rs index 527a3a0b..87f60f0a 100644 --- a/kit/src/behaviors/token_admin.rs +++ b/kit/src/behaviors/token_admin.rs @@ -10,6 +10,11 @@ use tracing::debug; use super::*; +#[derive(Deserialize, Serialize, Clone, Debug)] +pub struct TokenAdmin { + pub data: S::Data, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Config { pub token_data: Vec, @@ -30,76 +35,6 @@ impl State for Processing { type Data = Self; } -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] -pub enum Response { - Success, - Failed, -} - -#[derive(Deserialize, Serialize, Clone, Debug)] -pub struct TokenAdmin { - pub data: S::Data, -} - -impl TokenAdmin { - async fn reply_token_data(&self, token_name: String, to: String) -> Result<()> { - let token_data = &self.data.tokens.get(&token_name).unwrap().0; - Ok(self.data.messager.send(To::Agent(to), token_data).await?) - } - async fn reply_address_of(&self, token_name: String, to: String) -> Result<()> { - let token_address = self.data.tokens.get(&token_name).unwrap().1.address(); - Ok(self - .data - .messager - .send(To::Agent(to), token_address) - .await?) - } - - async fn reply_get_asset_universe(&self, to: String) -> Result<()> { - let asset_universe = self - .data - .tokens - .values() - .map(|(meta, token)| (meta, token.address())) - .collect::>(); - - Ok(self - .data - .messager - .send(To::Agent(to), asset_universe) - .await?) - } - - async fn reply_mint_request(&self, mint_request: MintRequest, to: String) -> Result<()> { - println!("Got to here in mint request"); - let token = &self.data.tokens.get(&mint_request.token).unwrap().1; - token - .mint( - mint_request.mint_to, - parse_ether(mint_request.mint_amount).unwrap(), - ) - .send() - .await? - .await?; - println!("Made the mint call to RPC in mint request"); - Ok(self - .data - .messager - .send(To::Agent(to), Response::Success) - .await?) - } -} - -/// Used as an action to ask what tokens are available. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub enum TokenAdminQuery { - AddressOf(String), - MintRequest(MintRequest), - GetAssetUniverse, - GetTokenData(String), - NoOp, -} -// Result) #[async_trait::async_trait] impl Behavior for TokenAdmin { type Processor = TokenAdmin; @@ -171,35 +106,88 @@ impl Processor for TokenAdmin { } } -mod test { - use std::{str::FromStr, sync::WaitTimeoutResult}; - - use arbiter_engine::{agent::Agent, world::World}; - use ethers::types::Address; - use futures_util::StreamExt; - use tracing::{level_filters::LevelFilter, Level}; - use tracing_subscriber::FmtSubscriber; - - use self::{ - bindings::{constant_sum_solver::ConstantSumParams, usdc::USDC}, - pool::constant_sum::ConstantSumPool, - }; - use super::*; - use crate::behaviors::behaviors::TokenAdmin; - - #[tokio::test(flavor = "multi_thread", worker_threads = 4)] - async fn token_admin_behavior_test() { - let subscriber = FmtSubscriber::builder() - .with_max_level(Level::DEBUG) - .pretty() - .finish(); - tracing::subscriber::set_global_default(subscriber).unwrap(); - - let mut world = World::new("test"); - let agent = Agent::builder("token_admin_agent"); - let token_admin_behavior = default_admin_config(); - world.add_agent(agent.with_behavior(token_admin_behavior)); - - world.run().await.unwrap(); +impl TokenAdmin { + async fn reply_token_data(&self, token_name: String, to: String) -> Result<()> { + let token_data = &self.data.tokens.get(&token_name).unwrap().0; + Ok(self.data.messager.send(To::Agent(to), token_data).await?) + } + async fn reply_address_of(&self, token_name: String, to: String) -> Result<()> { + let token_address = self.data.tokens.get(&token_name).unwrap().1.address(); + Ok(self + .data + .messager + .send(To::Agent(to), token_address) + .await?) + } + + async fn reply_get_asset_universe(&self, to: String) -> Result<()> { + let asset_universe = self + .data + .tokens + .values() + .map(|(meta, token)| (meta, token.address())) + .collect::>(); + + Ok(self + .data + .messager + .send(To::Agent(to), asset_universe) + .await?) + } + + async fn reply_mint_request(&self, mint_request: MintRequest, to: String) -> Result<()> { + println!("Got to here in mint request"); + let token = &self.data.tokens.get(&mint_request.token).unwrap().1; + token + .mint( + mint_request.mint_to, + parse_ether(mint_request.mint_amount).unwrap(), + ) + .send() + .await? + .await?; + println!("Made the mint call to RPC in mint request"); + Ok(self + .data + .messager + .send(To::Agent(to), Response::Success) + .await?) } } + +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct TokenData { + pub name: String, + pub symbol: String, + pub decimals: u8, + pub address: Option, +} + +/// Used as an action to ask what tokens are available. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub enum TokenAdminQuery { + AddressOf(String), + MintRequest(MintRequest), + GetAssetUniverse, + GetTokenData(String), + NoOp, +} + +/// Used as an action to mint tokens. +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct MintRequest { + /// The token to mint. + pub token: String, + + /// The address to mint to. + pub mint_to: eAddress, + + /// The amount to mint. + pub mint_amount: u64, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +pub enum Response { + Success, + Failed, +} diff --git a/kit/src/lib.rs b/kit/src/lib.rs index 6a4130d7..6edcfd45 100644 --- a/kit/src/lib.rs +++ b/kit/src/lib.rs @@ -4,30 +4,7 @@ pub mod pool; use anyhow::Result; use arbiter_core::middleware::ArbiterMiddleware; +pub use behaviors::token_admin::TokenData; use ethers::types::{Address as eAddress, U256 as eU256}; use serde::{Deserialize, Serialize}; use tracing::{error, info, trace, warn}; - -pub const WAD: eU256 = eU256([1_000_000_000_000_000_000, 0, 0, 0]); -pub const MAX: eU256 = eU256::MAX; - -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct TokenData { - pub name: String, - pub symbol: String, - pub decimals: u8, - pub address: Option, -} - -/// Used as an action to mint tokens. -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct MintRequest { - /// The token to mint. - pub token: String, - - /// The address to mint to. - pub mint_to: eAddress, - - /// The amount to mint. - pub mint_amount: u64, -} diff --git a/kit/src/pool/constant_sum.rs b/kit/src/pool/constant_sum.rs index 699aebf0..5ff3e160 100644 --- a/kit/src/pool/constant_sum.rs +++ b/kit/src/pool/constant_sum.rs @@ -116,8 +116,8 @@ impl PoolType for ConstantSumPool { async fn change_allocation_data( &self, - pool_id: eU256, - allocation_data: Self::AllocationData, + _pool_id: eU256, + _allocation_data: Self::AllocationData, ) -> Result { todo!() // match allocation_data { diff --git a/kit/src/pool/mod.rs b/kit/src/pool/mod.rs index cb1944cf..00289501 100644 --- a/kit/src/pool/mod.rs +++ b/kit/src/pool/mod.rs @@ -165,7 +165,7 @@ impl Pool

{ controller_fee: eU256::zero(), }; - let (id, _reserves, _total_liquidty) = dfmm.init(init_params.clone()).call().await?; + let (id, _reserves, _total_liquidity) = dfmm.init(init_params.clone()).call().await?; dfmm.init(init_params).send().await?.await?; let pool: shared_types::Pool = dfmm.pools(id).call().await?; let instance = P::create_instance(strategy_contract, solver_contract, params); @@ -181,6 +181,7 @@ impl Pool

{ info!("Pool created!\n {:#?}", pool); Ok(pool) } + /// Performs a swap on the pool. /// /// # Arguments diff --git a/kit/tests/common.rs b/kit/tests/common.rs new file mode 100644 index 00000000..2037eaf0 --- /dev/null +++ b/kit/tests/common.rs @@ -0,0 +1,72 @@ +use arbiter_engine::{agent::Agent, world::World}; +use dfmm_kit::{ + behaviors::{ + creator::{self, Creator}, + deployer::Deployer, + token_admin::{self, TokenAdmin}, + }, + pool::{ + constant_sum::{ConstantSumAllocationData, ConstantSumParams, ConstantSumPool}, + BaseConfig, + }, + TokenData, +}; +use ethers::types::U256 as eU256; +use tracing::Level; +use tracing_subscriber::FmtSubscriber; + +pub const WAD: eU256 = eU256([1_000_000_000_000_000_000, 0, 0, 0]); + +pub fn log() { + let subscriber = FmtSubscriber::builder() + .with_max_level(Level::DEBUG) + .pretty() + .finish(); + tracing::subscriber::set_global_default(subscriber).unwrap(); +} + +pub fn spawn_deployer(world: &mut World) { + let behavior = Deployer {}; + world.add_agent(Agent::builder("deployer").with_behavior(behavior)); +} + +pub fn spawn_token_admin(world: &mut World) { + let token1 = TokenData { + name: "US Dollar Coin".to_owned(), + symbol: "USDC".to_owned(), + decimals: 18, + address: None, + }; + + let token2 = TokenData { + name: "ShibaInuObamaSonic Coin".to_owned(), + symbol: "SIOS".to_owned(), + decimals: 18, + address: None, + }; + let config = token_admin::Config { + token_data: vec![token1, token2], + }; + let behavior = TokenAdmin:: { data: config }; + world.add_agent(Agent::builder("token_admin").with_behavior(behavior)); +} + +pub fn spawn_creator(world: &mut World) { + let behavior = Creator::> { + data: creator::Config { + params: ConstantSumParams { price: WAD }, + token_list: vec!["Token X".to_string(), "Token Y".to_string()], + base_config: BaseConfig { + name: "Test Pool".to_string(), + symbol: "TP".to_string(), + swap_fee: 10000.into(), + controller_fee: 0.into(), + }, + allocation_data: ConstantSumAllocationData { + reserve_x: WAD, + reserve_y: WAD, + }, + }, + }; + world.add_agent(Agent::builder("creator").with_behavior(behavior)); +} diff --git a/kit/tests/creator_integration.rs b/kit/tests/creator_integration.rs new file mode 100644 index 00000000..d112be8a --- /dev/null +++ b/kit/tests/creator_integration.rs @@ -0,0 +1,11 @@ +include!("common.rs"); + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn creator_behavior_test() { + let mut world = World::new("test"); + spawn_deployer(&mut world); + spawn_token_admin(&mut world); + spawn_creator(&mut world); + + world.run().await.unwrap(); +} diff --git a/kit/tests/deployer.rs b/kit/tests/deployer.rs new file mode 100644 index 00000000..a21992ad --- /dev/null +++ b/kit/tests/deployer.rs @@ -0,0 +1,49 @@ +include!("common.rs"); + +use dfmm_kit::behaviors::deployer::DeploymentData; +use ethers::types::Address as eAddress; +use std::str::FromStr; +use tracing::info; + +#[tokio::test(flavor = "multi_thread", worker_threads = 5)] +async fn creator_behavior_test() { + log(); + let mut world = World::new("test"); + let mut messager = world.messager.clone(); + + spawn_deployer(&mut world); + + world.run().await.unwrap(); + + if let Ok(message) = messager.get_next::().await { + let data = message.data; + info!("Saw message data: {:#?}", data); + + assert_eq!( + eAddress::from_str("0xd26df90ce64eefc85fbfa01de29b8d8db161166e").unwrap(), + data.weth + ); + assert_eq!( + eAddress::from_str("0x4dcb76f01b5624fecb5c7663892cb7977e9aaaa0").unwrap(), + data.dfmm + ); + assert_eq!( + eAddress::from_str("0x8b0190d573c655293f1266ab9c8121f3a7ddbffc").unwrap(), + data.geometric_mean + ); + assert_eq!( + eAddress::from_str("0xe57772db8a9609c7832c126d7416c172ea8073db").unwrap(), + data.log_normal + ); + assert_eq!( + eAddress::from_str("0xefe90bf7114239ba5bd78f8ecb25169ccb79d421").unwrap(), + data.constant_sum + ); + assert_eq!( + eAddress::from_str("0x73e04be543b6cd0452ee4b4f3702b3dd72c0f9f0").unwrap(), + data.n_token_geometric_mean + ); + } else { + panic!("No message received"); + } +} diff --git a/kit/tests/token_admin_integration.rs b/kit/tests/token_admin_integration.rs new file mode 100644 index 00000000..bf7302d8 --- /dev/null +++ b/kit/tests/token_admin_integration.rs @@ -0,0 +1,10 @@ +include!("common.rs"); + +#[tokio::test(flavor = "multi_thread", worker_threads = 4)] +async fn run_token_admin() { + let mut world = World::new("test"); + spawn_deployer(&mut world); + spawn_token_admin(&mut world); + + world.run().await.unwrap(); +}