Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: initialize/allocation behavior(s) #41

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
286 changes: 249 additions & 37 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions kit/Cargo.toml
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@ futures-util = "0.3.30"
# Serde
serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"
serde_traitobject = "0.2.8"

# Errors and tracing
anyhow = "1.0.80"
58 changes: 41 additions & 17 deletions kit/src/behaviors/deployer.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
use arbiter_bindings::bindings::weth::WETH;
use arbiter_engine::messager::To;
use bindings::{
constant_sum::ConstantSum, dfmm::DFMM, geometric_mean::GeometricMean, log_normal::LogNormal,
};
use ethers::types::Address;

use super::*;

#[derive(Debug, Deserialize, Serialize)]
pub struct Deployer {}
#[derive(Debug, Deserialize, Serialize)]
pub struct DeploymentData {
pub weth: Address,
pub dfmm: Address,
pub geometric_mean: Address,
pub log_normal: Address,
pub constant_sum: Address,
pub token_x: Address,
pub token_y: Address,
pub weth: eAddress,
pub dfmm: eAddress,
pub geometric_mean: eAddress,
pub geometric_mean_solver: eAddress,
pub log_normal: eAddress,
pub log_normal_solver: eAddress,
pub constant_sum: eAddress,
pub constant_sum_solver: eAddress,
pub token_x: eAddress,
pub token_y: eAddress,
}

#[async_trait::async_trait]
@@ -36,25 +34,48 @@ impl Behavior<()> for Deployer {
let geometric_mean = GeometricMean::deploy(client.clone(), dfmm.address())?
.send()
.await?;
trace!("GeometricMean deployed at {:?}", geometric_mean.address());
let geometric_mean_solver =
GeometricMeanSolver::deploy(client.clone(), geometric_mean.address())?
.send()
.await?;
trace!(
"GeometricMean deployed at {:?} with solver at {:?}",
geometric_mean.address(),
geometric_mean_solver.address()
);

let log_normal = LogNormal::deploy(client.clone(), dfmm.address())?
.send()
.await?;
trace!("LogNormal deployed at {:?}", log_normal.address());
let log_normal_solver = LogNormalSolver::deploy(client.clone(), log_normal.address())?
.send()
.await?;
trace!(
"LogNormal deployed at {:?} with solver at {:?}",
log_normal.address(),
log_normal_solver.address()
);

let constant_sum = ConstantSum::deploy(client.clone(), dfmm.address())?
.send()
.await?;
trace!("ConstantSum deployed at {:?}", constant_sum.address());
let constant_sum_solver =
ConstantSumSolver::deploy(client.clone(), constant_sum.address())?
.send()
.await?;
trace!(
"ConstantSum deployed at {:?} with solver at {:?}",
constant_sum.address(),
constant_sum_solver.address()
);

let token_x = arbiter_bindings::bindings::arbiter_token::ArbiterToken::deploy(
let token_x = ArbiterToken::deploy(
client.clone(),
("Token X".to_owned(), "ARBX".to_owned(), 18u8),
)?
.send()
.await?;
let token_y = arbiter_bindings::bindings::arbiter_token::ArbiterToken::deploy(
let token_y = ArbiterToken::deploy(
client.clone(),
("Token Y".to_owned(), "ARBY".to_owned(), 18u8),
)?
@@ -71,8 +92,11 @@ impl Behavior<()> for Deployer {
weth: weth.address(),
dfmm: dfmm.address(),
geometric_mean: geometric_mean.address(),
geometric_mean_solver: geometric_mean_solver.address(),
log_normal: log_normal.address(),
log_normal_solver: log_normal_solver.address(),
constant_sum: constant_sum.address(),
constant_sum_solver: constant_sum_solver.address(),
token_x: token_x.address(),
token_y: token_y.address(),
};
53 changes: 53 additions & 0 deletions kit/src/behaviors/initialize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use self::bindings::idfmm::InitParams;
use super::*;

#[derive(Debug, Deserialize, Serialize)]
pub struct Initialize {
pub rx: Option<eU256>,
pub ry: Option<eU256>,
pub pool_parameters: PoolParameters,
}

#[derive(Debug, Deserialize, Serialize)]
pub enum PoolParameters {
ConstantSum(ConstantSumParams),
}

#[async_trait::async_trait]
impl Behavior<()> for Initialize {
async fn startup(
&mut self,
client: Arc<ArbiterMiddleware>,
mut messager: Messager,
) -> Result<Option<EventStream<()>>> {
// await the deployment of DFMM contracts
while let Ok(message) = messager.get_next().await {
let deployment_data = match serde_json::from_str::<DeploymentData>(&message.data) {
Ok(data) => data,
Err(_) => continue,
};
match &self.pool_parameters {
PoolParameters::ConstantSum(params) => {
let solver =
ConstantSumSolver::new(deployment_data.constant_sum, client.clone());
let data = solver
.get_initial_pool_data(self.rx.unwrap(), self.ry.unwrap(), params.clone())
.call()
.await?;
let dfmm = DFMM::new(deployment_data.dfmm, client);
dfmm.init(InitParams {
strategy: deployment_data.constant_sum,
token_x: deployment_data.token_x,
token_y: deployment_data.token_y,
data,
})
.send()
.await?
.await?;
break;
}
}
}
Ok(None)
}
}
18 changes: 18 additions & 0 deletions kit/src/behaviors/liquidity_provision/initial.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use super::*;

#[derive(Debug, Deserialize, Serialize)]
pub struct Initial {
pub input_x: Option<eU256>,
pub input_y: Option<eU256>,
pub price: eU256,
}

impl AllocationType<()> for Initial {
fn change_allocation_amount(self, event: ()) -> Option<Allocation> {
Some(Allocation {
amount_x: self.input_x.map(I256::from_raw),
amount_y: self.input_y.map(I256::from_raw),
price: Some(self.price),
})
}
}
52 changes: 52 additions & 0 deletions kit/src/behaviors/liquidity_provision/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use std::fmt::Debug;
use std::marker::PhantomData;

use ethers::types::I256;
use serde::de::DeserializeOwned;

use super::*;

pub mod initial;

#[derive(Debug, Deserialize, Serialize)]
pub struct LiquidityProvision<A, E>
where
A: AllocationType<E>,
E: Debug + Send + Sync,
{
pub allocation_type: A,
// #[serde(skip)]
// pub pool: Option<Pool<P>>,
#[serde(skip)]
pub client: Option<Arc<ArbiterMiddleware>>,
#[serde(skip)]
pub messager: Option<Messager>,
phantom: PhantomData<E>,
}

pub trait AllocationType<E>: Send + Sync + Debug + Serialize + 'static {
fn change_allocation_amount(self, event: E) -> Option<Allocation>;
}

pub struct Allocation {
pub amount_x: Option<I256>,
pub amount_y: Option<I256>,
pub price: Option<eU256>,
}

#[async_trait::async_trait]
impl<A, E> Behavior<E> for LiquidityProvision<A, E>
where
A: AllocationType<E> + DeserializeOwned,
E: Debug + Send + Sync + 'static,
{
async fn startup(
&mut self,
client: Arc<ArbiterMiddleware>,
messager: Messager,
) -> Result<Option<EventStream<E>>> {
self.client = Some(client);
self.messager = Some(messager);
Ok(None)
}
}
4 changes: 3 additions & 1 deletion kit/src/behaviors/mod.rs
Original file line number Diff line number Diff line change
@@ -7,10 +7,12 @@ use arbiter_engine::{
use arbiter_macros::Behaviors;
use serde::{Deserialize, Serialize};

use self::deployer::Deployer;
pub use self::deployer::{Deployer, DeploymentData};
use super::*;

pub mod deployer;
pub mod initialize;
pub mod liquidity_provision;

#[derive(Behaviors, Debug, Deserialize, Serialize)]
pub enum Behaviors {
16 changes: 14 additions & 2 deletions kit/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
pub mod behaviors;
pub mod bindings;
pub mod pool;

use anyhow::Result;
use arbiter_bindings::bindings::arbiter_token::ArbiterToken;
use arbiter_core::middleware::ArbiterMiddleware;
use ethers::types::U256 as eU256;
use bindings::{
constant_sum::ConstantSum,
constant_sum_solver::{ConstantSumParams, ConstantSumSolver},
dfmm::DFMM,
geometric_mean::GeometricMean,
geometric_mean_solver::{GeometricMeanParams, GeometricMeanSolver},
log_normal::LogNormal,
log_normal_solver::{LogNormalParams, LogNormalSolver},
weth::WETH,
};
use ethers::types::{Address as eAddress, U256 as eU256};
use pool::{constant_sum::ConstantSumPool, Pool, PoolType, Token};
use serde::{Deserialize, Serialize};
use tracing::trace;
18 changes: 6 additions & 12 deletions kit/src/pool/constant_sum.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,32 @@
use bindings::{constant_sum::ConstantSum, constant_sum_solver::ConstantSumSolver};

use super::*;

#[derive(Debug)]
pub struct ConstantSumPool {
pub strategy_contract: ConstantSum<ArbiterMiddleware>,
pub solver_contract: ConstantSumSolver<ArbiterMiddleware>,
pub parameters: ConstantSumParameters,
}

pub struct ConstantSumParameters {
pub price: eU256,
pub swap_fee: eU256,
pub parameters: ConstantSumParams,
}

impl PoolType for ConstantSumPool {
type Parameters = ConstantSumParameters;
type Parameters = ConstantSumParams;
type StrategyContract = ConstantSum<ArbiterMiddleware>;
type SolverContract = ConstantSumSolver<ArbiterMiddleware>;
type AllocationData = (AllocateOrDeallocate, eU256, eU256);

async fn swap_data(
&self,
pool_id: eU256,
input_token: InputToken,
input_token: Token,
amount_in: eU256,
) -> Result<Bytes> {
let (valid, _, data) = match input_token {
InputToken::TokenX => {
Token::TokenX => {
self.solver_contract
.simulate_swap(pool_id, true, amount_in)
.call()
.await?
}
InputToken::TokenY => {
Token::TokenY => {
self.solver_contract
.simulate_swap(pool_id, false, amount_in)
.call()
17 changes: 10 additions & 7 deletions kit/src/pool/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Debug;

use arbiter_core::middleware::ArbiterMiddleware;
use ethers::types::Bytes;

@@ -9,14 +11,14 @@ pub mod constant_sum;
pub mod geometric_mean;
pub mod log_normal;

pub trait PoolType {
pub trait PoolType: Debug + Send + Sync {
type Parameters;
type StrategyContract;
type SolverContract;
type AllocationData;

#[allow(async_fn_in_trait)]
async fn swap_data(&self, pool_id: eU256, swap: InputToken, amount_in: eU256) -> Result<Bytes>;
async fn swap_data(&self, pool_id: eU256, swap: Token, amount_in: eU256) -> Result<Bytes>;
/// Change Parameters
#[allow(async_fn_in_trait)]
async fn update_data(&self, new_data: Self::Parameters) -> Result<Bytes>;
@@ -29,7 +31,7 @@ pub trait PoolType {
) -> Result<Bytes>;
}

pub enum InputToken {
pub enum Token {
TokenX,
TokenY,
}
@@ -39,23 +41,24 @@ pub enum AllocateOrDeallocate {
Deallocate,
}

#[derive(Debug)]
pub struct Pool<P: PoolType> {
pub id: eU256,
pub dfmm: DFMM<ArbiterMiddleware>,
pub instance: P,
pub dfmm: DFMM<ArbiterMiddleware>,
pub token_x: ArbiterToken<ArbiterMiddleware>,
pub token_y: ArbiterToken<ArbiterMiddleware>,
}

impl<P: PoolType> Pool<P> {
pub async fn swap(&self, amount_in: eU256, token_in: InputToken) -> Result<()> {
pub async fn swap(&self, amount_in: eU256, token_in: Token) -> Result<()> {
let data = match token_in {
InputToken::TokenX => {
Token::TokenX => {
self.instance
.swap_data(self.id, token_in, amount_in)
.await?
}
InputToken::TokenY => {
Token::TokenY => {
self.instance
.swap_data(self.id, token_in, amount_in)
.await?