Skip to content

Commit

Permalink
feat: Kit Behaviors and Tests (#130)
Browse files Browse the repository at this point in the history
* feat: LogNormalSolver

* wip: save constant sum

* feat: constant sum

* Add `PairSolver` abstract contract to avoid custom allo/deallo delta computations

* chore: natspec

* chore: bindings

* feat: constant sum pool type

* feat: geometric mean pool type

* feat: log normal pool type

* feat: n token geometric mean

* feat: n token geometric mean

* return abi encoded allo/deallo data

* feat: n-token bindings + pool types + tests

* feat: n-token pooltype

* feat: deploy n token geometric mean

* feat: generic allocate and deallocate and update

* feat: token admin

* feat: mint request

* feat: super generic <A, P, E> type state Processor

* fix: `Behaviors` enum with generic

* fix: trait redundances and serde

* clean up / constantsum

* test runs but we hit a revert

* feat: token admin

* debug: ruled out token aprovals and mints

* chore: notes on create pool

* wip: debug minting

* chore: some cleaning 🧼

* refactor: tests

* refactor: creator

* clean up more

* chore: clippy is happy

* feat: swap behavior startup

* test: geometric mean pool creator test

* wip: swap trait and parameter clean up

* feat: updator

* feat: swap and updatoor are vibing

* creator integration test debuging

* refactor / allocate builds

* chore: test compile with new names

* chore: deployer tests

* wip: save, going on walk

* fix token test

* chore: update test

* chore: update test

* wip: isolate bug

* Update update_integration.rs

* chore: message type match

* fix the loop

* annoying stupid serde

* chore: onto great things (contract reverts)

* wip: save

* fixed updater startup

* chore: Updater tests passing

* chore: Clean up + Starting swap integration tests

* chore: Clean up + Starting swap integration tests

* test: swap integration

* Update mod.rs

---------

Co-authored-by: kinrezc <matt.czernik@gmail.com>
Co-authored-by: Clément Lakhal <39790678+clemlak@users.noreply.github.com>
Co-authored-by: Colin Roberts <colin@primitive.xyz>
  • Loading branch information
4 people authored Apr 23, 2024
1 parent 4e207a7 commit b7e3c47
Show file tree
Hide file tree
Showing 98 changed files with 27,843 additions and 10,693 deletions.
688 changes: 341 additions & 347 deletions Cargo.lock

Large diffs are not rendered by default.

5,586 changes: 0 additions & 5,586 deletions kit/Cargo.lock

This file was deleted.

10 changes: 5 additions & 5 deletions kit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ keywords = ["ethereum", "smart-contracts", "automated market makers"]
readme = "../README.md"

[dependencies]
arbiter-core = "0.10.2"
arbiter-engine = "0.3.0"
arbiter-macros = "0.1.2"
arbiter-bindings = "0.1.6"
arbiter-core = { git = "https://github.com/primitivefinance/arbiter.git", rev = "aff29d30" }
arbiter-engine = { git = "https://github.com/primitivefinance/arbiter.git", rev = "aff29d30" }
arbiter-macros = { git = "https://github.com/primitivefinance/arbiter.git", rev = "aff29d30" }
arbiter-bindings = { git = "https://github.com/primitivefinance/arbiter.git", rev = "aff29d30" }

# Ethereum
ethers = "2.0.13"
Expand All @@ -27,7 +27,7 @@ serde = { version = "1.0.197", features = ["derive"] }
serde_json = "1.0.114"

# Errors and tracing
anyhow = "1.0.80"
anyhow = "1.0.81"
tracing = "0.1.40"
tracing-subscriber = "0.3.18"

Expand Down
6 changes: 6 additions & 0 deletions kit/configs/test.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
[[deployer]]
Deployer = {}

[[token_admin]]
TokenAdmin = { init_token_data = [
{ name = "US Dollar Coin", symbol = "USDC", decimals = 18 },
{ name = "Wrapped Ether", symbol = "WETH", decimals = 18 },
] }
13 changes: 7 additions & 6 deletions kit/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#[allow(unused)]
use dfmm_kit::behaviors::*;

#[arbiter_macros::main(
name = "DFMM Kit",
about = "Our entrypoint to working with the DFMM Kit.",
behaviors = Behaviors
)]
pub async fn main() {}
// #[arbiter_macros::main(
// name = "DFMM Kit",
// about = "Our entrypoint to working with the DFMM Kit.",
// behaviors = Behaviors
// )]
pub fn main() {}
83 changes: 83 additions & 0 deletions kit/src/behaviors/allocate/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use super::*;

pub trait AllocateType<E>: Debug + Serialize + Clone
where
E: Send + 'static,
{
// TODO: This should probably be how we do it, but this generic `P` gets
// annoying fn change_allocation_amount(&mut self, event: E) ->
// Option<P::AllocationData>;
fn change_allocation_amount(&mut self, event: E) -> Option<Vec<eI256>>;
fn get_stream(&self) -> Pin<Box<dyn Stream<Item = E> + Send + Sync>>;
}

#[derive(Clone, Debug, Serialize, Deserialize)]
struct Allocate<A, E, S>
where
A: AllocateType<E>,
E: Send + 'static,
S: State,
{
pub data: S::Data,
pub allocate_type: A,
_phantom_a: PhantomData<A>,
_phantom_e: PhantomData<E>,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Config<P: PoolType> {
pub allocation_data: P::AllocationData,
}

pub struct Processing<P, E>
where
P: PoolType,
E: Send + 'static,
{
pub pool: Pool<P>,
pub client: Arc<ArbiterMiddleware>,
pub messager: Messager,
_phantom: PhantomData<E>,
}

impl<P: PoolType> State for Config<P> {
type Data = Self;
}

impl<P, E> State for Processing<P, E>
where
P: PoolType,
E: Send + 'static,
{
type Data = Self;
}

#[allow(unused_variables)]
#[async_trait::async_trait]
impl<A, P, E> Behavior<E> for Allocate<A, E, Config<P>>
where
A: AllocateType<E> + Debug + Send + Sync + 'static + for<'a> Deserialize<'a>,
P: PoolType + Debug + Send + Sync + 'static,
E: Debug + Send + Sync + 'static,
{
type Processor = Allocate<A, E, Processing<P, E>>;
async fn startup(
&mut self,
client: Arc<ArbiterMiddleware>,
messager: Messager,
) -> Result<Option<(Self::Processor, EventStream<E>)>> {
todo!();
}
}

#[async_trait::async_trait]
impl<A, P, E> Processor<E> for Allocate<A, E, Processing<P, E>>
where
A: AllocateType<E> + Debug + Send + Sync + 'static,
P: PoolType + Debug + Send + Sync + 'static,
E: Debug + Send + Sync + 'static,
{
async fn process(&mut self, _event: E) -> Result<ControlFlow> {
Ok(ControlFlow::Halt)
}
}
126 changes: 126 additions & 0 deletions kit/src/behaviors/creator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
use super::*;
use crate::behaviors::token::Response;

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Create<S: State> {
pub token_admin: String,
pub data: S::Data,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Config<P: PoolType> {
pub base_config: BaseConfig,
pub params: P::Parameters,
pub allocation_data: P::AllocationData,
pub token_list: Vec<String>,
}

impl<P: PoolType> State for Config<P> {
type Data = Self;
}

#[async_trait::async_trait]
impl<P> Behavior<()> for Create<Config<P>>
where
P: PoolType + Send + Sync + 'static,
P::StrategyContract: Send,
P::SolverContract: Send,
{
type Processor = ();
async fn startup(
&mut self,
client: Arc<ArbiterMiddleware>,
mut messager: Messager,
) -> Result<Option<(Self::Processor, EventStream<()>)>> {
// Receive the `DeploymentData` from the `Deployer` agent and use it to get the
// contracts.
debug!("Starting the creator");
let deployment_data = messager.get_next::<DeploymentData>().await?.data;

debug!("Creator: Received deployment data {:?}", deployment_data);
let (strategy_contract, solver_contract) =
P::get_contracts(&deployment_data, client.clone());
let dfmm = DFMM::new(deployment_data.dfmm, client.clone());

// Get the intended tokens for the pool and do approvals.
let mut tokens = Vec::new();
for tkn in self.data.token_list.drain(..) {
messager
.send(
To::Agent(self.token_admin.clone()),
TokenAdminQuery::AddressOf(tkn.clone()),
)
.await
.unwrap();
let token = ArbiterToken::new(
messager.get_next::<eAddress>().await.unwrap().data,
client.clone(),
);
messager
.send(
To::Agent(self.token_admin.clone()),
TokenAdminQuery::MintRequest(MintRequest {
token: tkn,
mint_to: client.address(),
mint_amount: 100_000_000_000,
}),
)
.await
.unwrap();
assert_eq!(
messager.get_next::<Response>().await.unwrap().data,
Response::Success
);
token
.approve(dfmm.address(), MAX)
.send()
.await
.unwrap()
.await
.unwrap();

tokens.push(token);
}
debug!(
"Setting Controller Address to self address: {:?}",
client.address()
);
if self.data.base_config.controller == eAddress::zero() {
self.data.base_config.controller = client.address();
}
let params = P::set_controller(self.data.params.clone(), client.address());

debug!("creating pool...");
let pool = Pool::<P>::new(
self.data.base_config.clone(),
params.clone(),
self.data.allocation_data.clone(),
strategy_contract,
solver_contract,
dfmm,
tokens,
)
.await?;

debug!("Pool created!\n {:#?}", pool);

let pool_creation = (
pool.id,
pool.tokens.iter().map(|t| t.address()).collect::<Vec<_>>(),
pool.liquidity_token.address(),
params,
self.data.allocation_data.clone(),
);
messager.send(To::All, pool_creation).await.unwrap();
Ok(None)
}
}

// TODO: We should be able to use this but it is currently hard to work with due
// to `serde::Deserialize`
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
pub struct PoolCreation<P: PoolType> {
pub id: eU256,
pub params: P::Parameters,
pub allocation_data: P::AllocationData,
}
108 changes: 108 additions & 0 deletions kit/src/behaviors/deploy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
use arbiter_bindings::bindings::weth::WETH;
use bindings::{
constant_sum::ConstantSum, constant_sum_solver::ConstantSumSolver,
geometric_mean::GeometricMean, geometric_mean_solver::GeometricMeanSolver,
log_normal::LogNormal, log_normal_solver::LogNormalSolver,
};

use super::*;
use crate::bindings::{
n_token_geometric_mean::NTokenGeometricMean,
n_token_geometric_mean_solver::NTokenGeometricMeanSolver,
};

#[derive(Debug, Deserialize, Serialize)]
pub struct Deploy {}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct DeploymentData {
pub weth: eAddress,
pub dfmm: eAddress,
pub geometric_mean: eAddress,
pub geometric_mean_solver: eAddress,
pub n_token_geometric_mean: eAddress,
pub n_token_geometric_mean_solver: eAddress,
pub log_normal: eAddress,
pub log_normal_solver: eAddress,
pub constant_sum: eAddress,
pub constant_sum_solver: eAddress,
}

#[async_trait::async_trait]
impl Behavior<()> for Deploy {
type Processor = ();
async fn startup(
&mut self,
client: Arc<ArbiterMiddleware>,
messager: Messager,
) -> Result<Option<(Self::Processor, EventStream<()>)>> {
let weth = WETH::deploy(client.clone(), ())?.send().await?;
trace!("WETH deployed at {:?}", weth.address());

let dfmm = DFMM::deploy(client.clone(), weth.address())?.send().await?;
trace!("DFMM deployed at {:?}", dfmm.address());

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(), dfmm.address())?
.send()
.await?;
trace!(
"GeometricMeanSolver deployed at {:?}",
geometric_mean.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(), dfmm.address())?
.send()
.await?;
trace!(
"LogNormalSolver deployed at {:?}",
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(), dfmm.address())?
.send()
.await?;
trace!("ConstantSumSolver deployed at {:?}", constant_sum.address());

let n_token_geometric_mean = NTokenGeometricMean::deploy(client.clone(), dfmm.address())?
.send()
.await?;

let n_token_geometric_mean_solver =
NTokenGeometricMeanSolver::deploy(client.clone(), dfmm.address())?
.send()
.await?;

let deployment_data = DeploymentData {
weth: weth.address(),
dfmm: dfmm.address(),
geometric_mean: geometric_mean.address(),
geometric_mean_solver: geometric_mean_solver.address(),
n_token_geometric_mean: n_token_geometric_mean.address(),
n_token_geometric_mean_solver: n_token_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(),
};

debug!("Deployments completed: {:#?}", deployment_data);

messager.send(To::All, deployment_data).await?;
Ok(None)
}
}
Loading

0 comments on commit b7e3c47

Please sign in to comment.