Skip to content

Commit

Permalink
Merge pull request #298 from paltalabs/feat/blend-soroswap-setup
Browse files Browse the repository at this point in the history
Blend Soroswap setup
  • Loading branch information
chopan123 authored Dec 11, 2024
2 parents a67c1c5 + 4264ad3 commit dadc6ef
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 16 deletions.
4 changes: 2 additions & 2 deletions apps/contracts/strategies/blend/src/blend_pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ pub fn withdraw(e: &Env, from: &Address, amount: &i128, config: &Config) -> (i12
pub fn claim(e: &Env, from: &Address, config: &Config) -> i128 {
let pool_client = BlendPoolClient::new(e, &config.pool);

// TODO: Check reserve_token_ids and how to get the correct one
pool_client.claim(from, &vec![&e, config.reserve_id], from)
// TODO: Hardcoded reserve_token_ids for now
pool_client.claim(from, &vec![&e, 0u32, 1u32, 2u32, 3u32], from)
}

pub fn perform_reinvest(e: &Env, config: &Config) -> Result<bool, StrategyError>{
Expand Down
2 changes: 1 addition & 1 deletion apps/contracts/strategies/blend/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ pub const SCALAR_9: i128 = 1_000_000_000;
/// The minimum amount of tokens than can be deposited or withdrawn from the vault
pub const MIN_DUST: i128 = 0_0010000;

pub const REWARD_THRESHOLD: i128 = 500_0000000;
pub const REWARD_THRESHOLD: i128 = 40_0000000;
24 changes: 23 additions & 1 deletion apps/contracts/strategies/blend/src/soroswap.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use defindex_strategy_core::StrategyError;
use soroban_sdk::{vec, Address, Env, IntoVal, Symbol, Val, Vec};
use soroban_sdk::{auth::{ContractContext, InvokerContractAuthEntry, SubContractInvocation}, vec, Address, Env, IntoVal, Symbol, Val, Vec};

use crate::storage::Config;

Expand All @@ -19,6 +19,28 @@ pub fn internal_swap_exact_tokens_for_tokens(
swap_args.push_back(to.to_val());
swap_args.push_back(deadline.into_val(e));

// Maybe instead of using the router directly, we should use the pair for swaps
let pair_address: Address = e.invoke_contract(
&config.router,
&Symbol::new(&e, "router_pair_for"),
vec![&e, path.get(0).unwrap().into_val(e), path.get(1).unwrap().into_val(e)]
);

e.authorize_as_current_contract(vec![
&e,
InvokerContractAuthEntry::Contract(SubContractInvocation {
context: ContractContext {
contract: path.get(0).unwrap().clone(),
fn_name: Symbol::new(&e, "transfer"),
args: (
e.current_contract_address(),
pair_address,
amount_in.clone()).into_val(e),
},
sub_invocations: vec![&e],
}),
]);

e.invoke_contract(
&config.router,
&Symbol::new(&e, "swap_exact_tokens_for_tokens"),
Expand Down
3 changes: 2 additions & 1 deletion apps/contracts/strategies/blend/src/test/blend/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mod success;
mod success;
mod soroswap_setup;
60 changes: 60 additions & 0 deletions apps/contracts/strategies/blend/src/test/blend/soroswap_setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use soroban_sdk::{
Env, BytesN, Address,
testutils::{Address as _}
};

fn pair_contract_wasm(e: &Env) -> BytesN<32> {
soroban_sdk::contractimport!(
file = "../external_wasms/soroswap/soroswap_pair.optimized.wasm"
);
e.deployer().upload_contract_wasm(WASM)
}

// SoroswapFactory Contract
mod factory {
soroban_sdk::contractimport!(file = "../external_wasms/soroswap/soroswap_factory.optimized.wasm");
pub type SoroswapFactoryClient<'a> = Client<'a>;
}
use factory::SoroswapFactoryClient;

pub fn create_soroswap_factory<'a>(e: &Env, setter: &Address) -> SoroswapFactoryClient<'a> {
let pair_hash = pair_contract_wasm(&e);
let factory_address = &e.register(factory::WASM, ());
let factory = SoroswapFactoryClient::new(e, factory_address);
factory.initialize(&setter, &pair_hash);
factory
}

// SoroswapRouter Contract
mod router {
soroban_sdk::contractimport!(file = "../external_wasms/soroswap/soroswap_router.optimized.wasm");
pub type SoroswapRouterClient<'a> = Client<'a>;
}
pub use router::SoroswapRouterClient;

// SoroswapRouter Contract
pub fn create_soroswap_router<'a>(e: &Env, factory: &Address) -> SoroswapRouterClient<'a> {
let router_address = &e.register(router::WASM, ());
let router = SoroswapRouterClient::new(e, router_address);
router.initialize(factory);
router
}

pub fn create_soroswap_pool<'a>(e: &Env, to: &Address, token_a: &Address, token_b: &Address, amount_a: &i128, amount_b: &i128) -> SoroswapRouterClient<'a> {
let soroswap_admin = Address::generate(&e);
let factory = create_soroswap_factory(&e, &soroswap_admin);
let router = create_soroswap_router(&e, &factory.address);

router.add_liquidity(
token_a,
token_b,
&amount_a,
&amount_b,
&0i128,
&0i128,
&to,
&(e.ledger().timestamp() + 3600)
);

router
}
37 changes: 26 additions & 11 deletions apps/contracts/strategies/blend/src/test/blend/success.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
use crate::blend_pool::{BlendPoolClient, Request};
use crate::constants::MIN_DUST;
use crate::storage::DAY_IN_LEDGERS;
use crate::test::blend::soroswap_setup::create_soroswap_pool;
use crate::test::{create_blend_pool, create_blend_strategy, BlendFixture, EnvTestUtils};
use crate::BlendStrategyClient;
use defindex_strategy_core::StrategyError;
Expand All @@ -25,18 +26,27 @@ fn success() {
let blnd = e.register_stellar_asset_contract_v2(admin.clone());
let usdc = e.register_stellar_asset_contract_v2(admin.clone());
let xlm = e.register_stellar_asset_contract_v2(admin.clone());
let _blnd_client = MockTokenClient::new(&e, &blnd.address());
let blnd_client = MockTokenClient::new(&e, &blnd.address());
let usdc_client = MockTokenClient::new(&e, &usdc.address());
let xlm_client = MockTokenClient::new(&e, &xlm.address());

// Setting up soroswap pool
let pool_admin = Address::generate(&e);
let amount_a = 100000000_0_000_000;
let amount_b = 50000000_0_000_000;
blnd_client.mint(&pool_admin, &amount_a);
usdc_client.mint(&pool_admin, &amount_b);
let soroswap_router = create_soroswap_pool(&e, &pool_admin, &blnd.address(), &usdc.address(), &amount_a, &amount_b);
// End of setting up soroswap pool

let blend_fixture = BlendFixture::deploy(&e, &admin, &blnd.address(), &usdc.address());

// usdc (0) and xlm (1) charge a fixed 10% borrow rate with 0% backstop take rate
// admin deposits 200m tokens and borrows 100m tokens for a 50% util rate
// emits to each reserve token evently, and starts emissions
let pool = create_blend_pool(&e, &blend_fixture, &admin, &usdc_client, &xlm_client);
let pool_client = BlendPoolClient::new(&e, &pool);
let strategy = create_blend_strategy(&e, &usdc.address(), &pool, &0u32, &blnd.address(), &Address::generate(&e));
let strategy = create_blend_strategy(&e, &usdc.address(), &pool, &0u32, &blnd.address(), &soroswap_router.address);
let strategy_client = BlendStrategyClient::new(&e, &strategy);

/*
Expand All @@ -51,7 +61,7 @@ fn success() {
usdc_client.mint(&user_2, &starting_balance);
usdc_client.mint(&user_3, &starting_balance);

let user_3_balance = usdc_client.balance(&user_2);
let user_3_balance = usdc_client.balance(&user_3);
assert_eq!(user_3_balance, starting_balance);


Expand Down Expand Up @@ -198,16 +208,12 @@ fn success() {
)
);

strategy_client.withdraw(&withdraw_amount, &user_3);

// -> verify withdraw
assert_eq!(usdc_client.balance(&user_2), withdraw_amount);
assert_eq!(usdc_client.balance(&user_3), withdraw_amount);
assert_eq!(strategy_client.balance(&user_2), 0);
assert_eq!(strategy_client.balance(&user_3), 0);

// -> verify withdraw from empty vault fails
let result = strategy_client.try_withdraw(&MIN_DUST, &user_3);
let result = strategy_client.try_withdraw(&MIN_DUST, &user_2);
assert_eq!(result, Err(Ok(StrategyError::InsufficientBalance)));

// TODO: Finish harvest testings, pending soroswap router setup with a blend token pair with the underlying asset
Expand All @@ -219,8 +225,17 @@ fn success() {
*/

// harvest
// strategy_client.harvest(&usdc, &user_2, &expected_fees);
let blnd_strategy_balance = blnd_client.balance(&strategy);
assert_eq!(blnd_strategy_balance, 0);

// -> verify harvest

strategy_client.harvest(&user_3);

let blnd_strategy_balance = blnd_client.balance(&strategy);
assert_eq!(blnd_strategy_balance, 0);

let usdc_strategy_balance = usdc_client.balance(&strategy);
assert_eq!(usdc_strategy_balance, 0);

let user_3_strategy_balance = strategy_client.balance(&user_3);
assert_eq!(user_3_strategy_balance, 1226627059);
}

0 comments on commit dadc6ef

Please sign in to comment.