Skip to content

Commit f34b90d

Browse files
committed
liqudiity manager g=functionality moved to separate module
1 parent 81a065f commit f34b90d

3 files changed

Lines changed: 126 additions & 66 deletions

File tree

src/liquidity_provider.rs

Lines changed: 24 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,26 @@ use ethers::prelude::*;
33
use std::sync::Arc;
44
use crate::pool::Pool;
55
use crate::onchain::erc20::ERC20Token;
6+
use crate::onchain::liquidity_manager::LiquidityManager;
67
use log::info;
78

89
pub struct LiquidityProvider<P> {
910
pool: Arc<Pool<P>>,
1011
provider: Provider<P>,
1112
num_ticks: u32,
12-
liquidity_manager_contract: Address,
13+
liquidity_manager: LiquidityManager<P>,
1314
}
1415

1516
impl<P: JsonRpcClient + Clone + 'static> LiquidityProvider<P> {
16-
pub fn new(pool: Arc<Pool<P>>, provider: Provider<P>, num_ticks: u32, liquidity_manager_contract: Address) -> Self {
17-
Self {
17+
pub fn new(pool: Arc<Pool<P>>, provider: Provider<P>, num_ticks: u32, liquidity_manager_contract: Address) -> Result<Self> {
18+
let liquidity_manager = LiquidityManager::new(provider.clone(), liquidity_manager_contract)?;
19+
20+
Ok(Self {
1821
pool,
1922
provider,
2023
num_ticks,
21-
liquidity_manager_contract,
22-
}
24+
liquidity_manager,
25+
})
2326
}
2427

2528
pub async fn provide_liquidity(&self, amount_a: U256, amount_b: U256) -> Result<()> {
@@ -37,79 +40,35 @@ impl<P: JsonRpcClient + Clone + 'static> LiquidityProvider<P> {
3740
let token_b_contract = ERC20Token::new(token_b, provider.clone());
3841

3942
// Approve tokens
40-
token_a_contract.approve(self.liquidity_manager_contract, amount_a).await?;
41-
token_b_contract.approve(self.liquidity_manager_contract, amount_b).await?;
42-
43-
let liq_manager_abi: ethers::abi::Abi = serde_json::from_str(include_str!("../contracts/out/LiqManager.sol/LiquidityManager.json"))?;
44-
let liq_manager_contract = Contract::new(
45-
self.liquidity_manager_contract,
46-
liq_manager_abi,
47-
provider
48-
);
49-
50-
let sqrt_lower = Self::tick_to_sqrt_price(bottom_tick);
51-
let sqrt_upper = Self::tick_to_sqrt_price(top_tick);
52-
let sqrt_current = Self::tick_to_sqrt_price(current_tick);
53-
54-
let liquidity_from_token0 = (amount_a.as_u128() as f64) * (sqrt_lower * sqrt_upper) / (sqrt_upper - sqrt_lower);
55-
let liquidity_from_token1 = (amount_b.as_u128() as f64) / (sqrt_upper - sqrt_lower);
56-
let liquidity = if sqrt_current <= sqrt_lower {
57-
liquidity_from_token0
58-
} else if sqrt_current >= sqrt_upper {
59-
liquidity_from_token1
60-
} else {
61-
liquidity_from_token0.min(liquidity_from_token1)
62-
};
63-
let liquidity_desired = U128::from(liquidity as u128);
64-
let data = Vec::<u8>::new();
43+
token_a_contract.approve(self.liquidity_manager.address, amount_a).await?;
44+
token_b_contract.approve(self.liquidity_manager.address, amount_b).await?;
6545

66-
let provide_call = liq_manager_contract
67-
.method::<_, H256>(
68-
"provideLiquidity",
69-
(
70-
self.liquidity_manager_contract,
71-
bottom_tick,
72-
top_tick,
73-
liquidity_desired,
74-
data,
75-
),
76-
)?;
77-
let tx = provide_call.send().await?;
46+
self.liquidity_manager.provide_liquidity(
47+
bottom_tick,
48+
top_tick,
49+
amount_a,
50+
amount_b,
51+
current_tick,
52+
).await?;
7853

79-
info!("Liquidity provided successfully. Transaction hash: {:?}", tx.tx_hash());
8054
Ok(())
8155
}
8256

8357
pub async fn remove_liquidity(&self, position_id: U256) -> Result<()> {
84-
let liq_manager_abi: ethers::abi::Abi = serde_json::from_str(include_str!("../contracts/out/LiqManager.sol/LiquidityManager.json"))?;
85-
let provider = Arc::new(self.provider.clone());
86-
let liq_manager_contract = Contract::new(
87-
self.liquidity_manager_contract,
88-
liq_manager_abi,
89-
provider
90-
);
91-
9258
let bottom_tick = -100;
9359
let top_tick = 100;
9460
let amount = U128::from(position_id.as_u128());
9561
let amount0_min = U256::from(0);
9662
let amount1_min = U256::from(0);
9763

98-
let withdraw_call = liq_manager_contract
99-
.method::<_, H256>(
100-
"withdrawLiquidity",
101-
(
102-
self.liquidity_manager_contract,
103-
bottom_tick,
104-
top_tick,
105-
amount,
106-
amount0_min,
107-
amount1_min,
108-
),
109-
)?;
110-
let tx = withdraw_call.send().await?;
64+
self.liquidity_manager.withdraw_liquidity(
65+
bottom_tick,
66+
top_tick,
67+
amount,
68+
amount0_min,
69+
amount1_min,
70+
).await?;
11171

112-
info!("Liquidity removed successfully. Transaction hash: {:?}", tx.tx_hash());
11372
Ok(())
11473
}
11574

src/onchain/liquidity_manager.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use anyhow::Result;
2+
use ethers::prelude::*;
3+
use std::sync::Arc;
4+
use log::info;
5+
6+
pub struct LiquidityManager<P> {
7+
contract: Contract<Arc<Arc<Provider<P>>>>,
8+
pub address: Address,
9+
}
10+
11+
impl<P: JsonRpcClient + Clone + 'static> LiquidityManager<P> {
12+
pub fn new(provider: Provider<P>, address: Address) -> Result<Self> {
13+
let abi: ethers::abi::Abi = serde_json::from_str(include_str!("../../contracts/out/LiqManager.sol/LiquidityManager.json"))?;
14+
let contract = Contract::new(address, abi, Arc::new(Arc::new(Arc::new(provider))));
15+
16+
Ok(Self {
17+
contract,
18+
address,
19+
})
20+
}
21+
22+
fn calculate_liquidity(
23+
amount_a: U256,
24+
amount_b: U256,
25+
bottom_tick: i32,
26+
top_tick: i32,
27+
current_tick: i32,
28+
) -> U128 {
29+
let sqrt_lower = Self::tick_to_sqrt_price(bottom_tick);
30+
let sqrt_upper = Self::tick_to_sqrt_price(top_tick);
31+
let sqrt_current = Self::tick_to_sqrt_price(current_tick);
32+
33+
let liquidity_from_token0 = (amount_a.as_u128() as f64) * (sqrt_lower * sqrt_upper) / (sqrt_upper - sqrt_lower);
34+
let liquidity_from_token1 = (amount_b.as_u128() as f64) / (sqrt_upper - sqrt_lower);
35+
let liquidity = if sqrt_current <= sqrt_lower {
36+
liquidity_from_token0
37+
} else if sqrt_current >= sqrt_upper {
38+
liquidity_from_token1
39+
} else {
40+
liquidity_from_token0.min(liquidity_from_token1)
41+
};
42+
U128::from(liquidity as u128)
43+
}
44+
45+
fn tick_to_sqrt_price(tick: i32) -> f64 {
46+
1.0001_f64.powf(tick as f64 / 2.0)
47+
}
48+
49+
pub async fn provide_liquidity(
50+
&self,
51+
bottom_tick: i32,
52+
top_tick: i32,
53+
amount_a: U256,
54+
amount_b: U256,
55+
current_tick: i32,
56+
) -> Result<H256> {
57+
let liquidity_desired = Self::calculate_liquidity(amount_a, amount_b, bottom_tick, top_tick, current_tick);
58+
let data = Vec::<u8>::new();
59+
60+
let provide_call = self.contract
61+
.method::<_, H256>(
62+
"provideLiquidity",
63+
(
64+
self.address,
65+
bottom_tick,
66+
top_tick,
67+
liquidity_desired,
68+
data,
69+
),
70+
)?;
71+
let tx = provide_call.send().await?;
72+
info!("Liquidity provided successfully. Transaction hash: {:?}", tx.tx_hash());
73+
Ok(tx.tx_hash())
74+
}
75+
76+
pub async fn withdraw_liquidity(
77+
&self,
78+
bottom_tick: i32,
79+
top_tick: i32,
80+
amount: U128,
81+
amount0_min: U256,
82+
amount1_min: U256,
83+
) -> Result<H256> {
84+
let withdraw_call = self.contract
85+
.method::<_, H256>(
86+
"withdrawLiquidity",
87+
(
88+
self.address,
89+
bottom_tick,
90+
top_tick,
91+
amount,
92+
amount0_min,
93+
amount1_min,
94+
),
95+
)?;
96+
let tx = withdraw_call.send().await?;
97+
info!("Liquidity removed successfully. Transaction hash: {:?}", tx.tx_hash());
98+
Ok(tx.tx_hash())
99+
}
100+
}

src/onchain/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod erc20;
2-
pub mod bulla_pool;
2+
pub mod bulla_pool;
3+
pub mod liquidity_manager;

0 commit comments

Comments
 (0)