Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/paltalabs/defindex into fix…
Browse files Browse the repository at this point in the history
…/mainTest
  • Loading branch information
MattPoblete committed Dec 11, 2024
2 parents 24d36a1 + dadc6ef commit 193bdee
Show file tree
Hide file tree
Showing 30 changed files with 1,748 additions and 665 deletions.
47 changes: 47 additions & 0 deletions apps/contracts/src/utils/tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,50 @@ export const getCurrentTimePlusOneHour = () => {

return oneHourLater;
};

export function getTransactionBudget(tx: any): { instructions: number, readBytes: number, writeBytes: number } {
const resources = tx.envelopeXdr.value().tx().ext().value().resources()
const warningTolerance = 0.85
const MAXWRITEBYTES = 132096
const MAXREADBYTES = 200000
const MAXINSTRUCTIONS = 100000000
const budget= {
instructions: resources.instructions(),
readBytes: resources.readBytes(),
writeBytes: resources.writeBytes(),
}
const getPercentage = (value: number, max: number)=>{
return (value * 100)/max
}
if(budget.instructions > MAXINSTRUCTIONS * warningTolerance){
console.warn('Instructions budget exceeded')
console.table({
value:{
instructions: budget.instructions,
maxInstructions: MAXINSTRUCTIONS,
'%': getPercentage(budget.instructions, MAXINSTRUCTIONS)
},
})
}
if(budget.readBytes > MAXREADBYTES * warningTolerance){
console.warn('ReadBytes budget exceeded')
console.table({
value: {
readBytes: budget.readBytes,
maxReadBytes: MAXREADBYTES,
'%': getPercentage(budget.readBytes, MAXREADBYTES)
}
})
}
if(budget.writeBytes > MAXWRITEBYTES * warningTolerance){
console.warn('WriteBytes budget exceeded')
console.table({
value:{
writeBytes: budget.writeBytes,
maxWriteBytes: MAXWRITEBYTES,
'%': getPercentage(budget.writeBytes, MAXWRITEBYTES)
}
})
}
return budget
}
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);
}
7 changes: 6 additions & 1 deletion apps/contracts/strategies/hodl/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct HodlStrategyTest<'a> {
env: Env,
token: TokenClient<'a>,
user: Address,
user1: Address,
}

impl<'a> HodlStrategyTest<'a> {
Expand All @@ -38,14 +39,18 @@ impl<'a> HodlStrategyTest<'a> {
let admin = Address::generate(&env);
let token = create_token_contract(&env, &admin);
let user = Address::generate(&env);
let user1 = Address::generate(&env);

// Mint 1,000,000,000 to user
StellarAssetClient::new(&env, &token.address).mint(&user, &1_000_000_000);
// Mint 1,000,000,000 to user1
StellarAssetClient::new(&env, &token.address).mint(&user1, &1_000_000_000);

HodlStrategyTest {
env,
token,
user
user,
user1,
}
}

Expand Down
33 changes: 31 additions & 2 deletions apps/contracts/strategies/hodl/src/test/hodl/deposit.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use crate::test::create_hodl_strategy;
use crate::test::HodlStrategyTest;
use crate::test::StrategyError;

// test deposit with negative amount
#[test]
fn deposit_with_negative_amount() {
Expand All @@ -27,7 +26,6 @@ fn deposit_mock_auths() {
fn deposit_and_withdrawal_flow() {
let test = HodlStrategyTest::setup();

// initialize
let strategy = create_hodl_strategy(&test.env, &test.token.address);

// Initial user token balance
Expand Down Expand Up @@ -71,4 +69,35 @@ fn deposit_and_withdrawal_flow() {
let result = strategy.try_withdraw(&amount_to_withdraw, &test.user);
assert_eq!(result, Err(Ok(StrategyError::InsufficientBalance)));

}

#[test]
fn deposit_from_a_withdrawal_from_b() {
let test = HodlStrategyTest::setup();
let strategy = create_hodl_strategy(&test.env, &test.token.address);

// Initial user token balance
let balance = test.token.balance(&test.user);

let amount = 123456;

// Deposit amount of token from the user to the strategy
strategy.deposit(&amount, &test.user);

let balance_after_deposit = test.token.balance(&test.user);
assert_eq!(balance_after_deposit, balance - amount);

// Reading strategy balance
let strategy_balance_after_deposit = test.token.balance(&strategy.address);
assert_eq!(strategy_balance_after_deposit, amount);

// Reading user balance on strategy contract
let user_balance_on_strategy = strategy.balance(&test.user);
assert_eq!(user_balance_on_strategy, amount);


let amount_to_withdraw = 100_000;
// Withdrawing token from the strategy to user
let result = strategy.try_withdraw(&amount_to_withdraw, &test.user1);
assert_eq!(result, Err(Ok(StrategyError::InsufficientBalance)));
}
Loading

0 comments on commit 193bdee

Please sign in to comment.