Skip to content

Commit

Permalink
Merge branch 'feat/v0.3.0' into feat/single-side-deposit
Browse files Browse the repository at this point in the history
  • Loading branch information
clemlak committed Apr 29, 2024
2 parents b6adfb8 + fbfb58d commit 8bd202d
Show file tree
Hide file tree
Showing 136 changed files with 35,706 additions and 5,224 deletions.
15 changes: 14 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,17 @@

[submodule "lib/forge-std"]
path = lib/forge-std
url = https://github.com/foundry-rs/forge-std
url = https://github.com/foundry-rs/forge-std

[submodule "lib/pendle-core-v2-public"]
path = lib/pendle-core-v2-public
url = https://github.com/pendle-finance/pendle-core-v2-public

[submodule "lib/openzeppelin-contracts"]
path = lib/openzeppelin-contracts
url = https://github.com/OpenZeppelin/openzeppelin-contracts
branch = v4.9.3

[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
> Version: `v0.3.0`
# DFMM

This repository contains the smart contracts source code for the DFMM protocol.



## What is DFMM?

The DFMM protocol is a novel portfolio management system designed to leverage external strategy contracts. This system separates the operational logic and the mathematical model: the `DFMM` core contract completely relies on the strategies to validate the state of each interaction. On the other hand, this core contract acts as a single entry point and performs all the operations, such as:
Expand Down
2 changes: 2 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
remappings = [
"solmate/=lib/solstat/lib/solmate/src/",
"solstat/=lib/solstat/src/",
"pendle/=lib/pendle-core-v2-public/contracts/"
]
solc_version = "0.8.22"

Expand All @@ -23,6 +24,7 @@ number_underscore = "thousands"
[rpc_endpoints]
local = "http://localhost:8545"
optimism_sepolia = "${OPTIMISM_SEPOLIA_RPC_URL}"
mainnet = "${MAINNET_RPC_URL}"

[etherscan]
optimism_sepolia = { key = "${ETHERSCAN_API_KEY}" }
18 changes: 18 additions & 0 deletions kit/src/behaviors/allocate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[allow(unused_imports)]
use arbiter_engine::machine::ControlFlow;

use super::*;

#[derive(Debug, Deserialize, Serialize)]
pub struct Allocate {}
#[allow(unused_variables)]
#[async_trait::async_trait]
impl Behavior<()> for Allocate {
async fn startup(
&mut self,
client: Arc<ArbiterMiddleware>,
messager: Messager,
) -> Result<Option<EventStream<()>>> {
Ok(None)
}
}
15 changes: 12 additions & 3 deletions kit/src/behaviors/deployer.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use arbiter_bindings::bindings::weth::WETH;
use arbiter_engine::messager::To;
use bindings::{
constant_sum::ConstantSum, dfmm::DFMM, geometric_mean::GeometricMean, log_normal::LogNormal,
};
Expand All @@ -11,6 +10,7 @@ use super::*;
pub struct Deployer {}
#[derive(Debug, Deserialize, Serialize)]
pub struct DeploymentData {
pub n_token_geometric_mean: Address,
pub weth: Address,
pub dfmm: Address,
pub geometric_mean: Address,
Expand Down Expand Up @@ -48,13 +48,13 @@ impl Behavior<()> for Deployer {
.await?;
trace!("ConstantSum deployed at {:?}", constant_sum.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),
)?
Expand All @@ -67,7 +67,12 @@ impl Behavior<()> for Deployer {
token_y.address()
);

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

let deployment_data = DeploymentData {
n_token_geometric_mean: n_token_geometric_mean.address(),
weth: weth.address(),
dfmm: dfmm.address(),
geometric_mean: geometric_mean.address(),
Expand Down Expand Up @@ -141,6 +146,10 @@ mod tests {
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");
}
Expand Down
19 changes: 16 additions & 3 deletions kit/src/behaviors/mod.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
use std::sync::Arc;

use arbiter_bindings::bindings::arbiter_token::ArbiterToken;
use arbiter_engine::{
machine::{Behavior, CreateStateMachine, Engine, EventStream, StateMachine},
messager::Messager,
machine::{Behavior, ControlFlow, CreateStateMachine, Engine, EventStream, StateMachine},
messager::{Message, Messager, To},
};
use arbiter_macros::Behaviors;
use serde::{Deserialize, Serialize};

use self::deployer::Deployer;
use self::{allocate::Allocate, deployer::Deployer, token_admin::TokenAdmin};
use super::*;

pub mod allocate;
pub mod deployer;
pub mod token_admin;

#[derive(Behaviors, Debug, Deserialize, Serialize)]
pub enum Behaviors {
Allocate(Allocate),
Deployer(Deployer),
TokenAdmin(TokenAdmin),
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TokenData {
pub name: String,
pub symbol: String,
pub decimals: u8,
pub address: Option<eAddress>,
}
128 changes: 128 additions & 0 deletions kit/src/behaviors/token_admin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
use std::collections::HashMap;

use super::*;

#[derive(Deserialize, Serialize, Clone, Debug)]
pub struct TokenAdmin {
/// The identifier of the token admin.
pub token_data: HashMap<String, TokenData>,
#[serde(skip)]
pub tokens: Option<HashMap<String, ArbiterToken<ArbiterMiddleware>>>,
#[serde(skip)]
pub client: Option<Arc<ArbiterMiddleware>>,
#[serde(skip)]
pub messager: Option<Messager>,
#[serde(default)]
pub count: u64,
#[serde(default = "default_max_count")]
pub max_count: Option<u64>,
}

pub fn default_max_count() -> Option<u64> {
Some(3)
}

/// Used as an action to ask what tokens are available.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum TokenAdminQuery {
/// Get the address of the token.
AddressOf(String),

/// Mint tokens.
MintRequest(MintRequest),
}

/// 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,
}

#[async_trait::async_trait]
impl Behavior<Message> for TokenAdmin {
#[tracing::instrument(skip(self), fields(id = messager.id.as_deref()))]
async fn startup(
&mut self,
client: Arc<ArbiterMiddleware>,
messager: Messager,
) -> Result<Option<EventStream<Message>>> {
self.messager = Some(messager.clone());
self.client = Some(client.clone());
for token_data in self.token_data.values_mut() {
let token = ArbiterToken::deploy(
client.clone(),
(
token_data.name.clone(),
token_data.symbol.clone(),
token_data.decimals,
),
)
.unwrap()
.send()
.await
.unwrap();

token_data.address = Some(token.address());
self.tokens
.get_or_insert_with(HashMap::new)
.insert(token_data.name.clone(), token.clone());
}
Ok(None)
}

#[tracing::instrument(skip(self), fields(id =
self.messager.as_ref().unwrap().id.as_deref()))]
async fn process(&mut self, event: Message) -> Result<ControlFlow> {
if self.tokens.is_none() {
error!(
"There were no tokens to deploy! You must add tokens to
the token admin before running the simulation."
);
}

let query: TokenAdminQuery = serde_json::from_str(&event.data).unwrap();
trace!("Got query: {:?}", query);
let messager = self.messager.as_ref().unwrap();
match query {
TokenAdminQuery::AddressOf(token_name) => {
trace!(
"Getting address of token with name: {:?}",
token_name.clone()
);
let token_data = self.token_data.get(&token_name).unwrap();
messager
.send(To::Agent(event.from.clone()), token_data.address)
.await?;
}
TokenAdminQuery::MintRequest(mint_request) => {
trace!("Minting tokens: {:?}", mint_request);
let token = self
.tokens
.as_ref()
.unwrap()
.get(&mint_request.token)
.unwrap();
token
.mint(mint_request.mint_to, eU256::from(mint_request.mint_amount))
.send()
.await
.unwrap()
.await
.unwrap();
self.count += 1;
if self.count == self.max_count.unwrap_or(u64::MAX) {
warn!("Reached max count. Halting behavior.");
return Ok(ControlFlow::Halt);
}
}
}
Ok(ControlFlow::Continue)
}
}
4 changes: 2 additions & 2 deletions kit/src/bindings/arb_math.rs

Large diffs are not rendered by default.

Loading

0 comments on commit 8bd202d

Please sign in to comment.