Skip to content

Commit

Permalink
Merge branch 'main' into router-further-audit-improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
psorinionut authored Apr 8, 2024
2 parents 310cd31 + 7787734 commit b542ecd
Show file tree
Hide file tree
Showing 9 changed files with 11 additions and 662 deletions.
263 changes: 2 additions & 261 deletions dex/farm/tests/farm_single_user_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ mod farm_setup;

use config::ConfigModule;
use farm_setup::single_user_farm_setup::*;
use multiversx_sc::{codec::multi_types::OptionalValue, types::EsdtLocalRole};
use multiversx_sc::types::EsdtLocalRole;
use multiversx_sc_scenario::{
managed_address, managed_biguint, managed_token_id, managed_token_id_wrapped, rust_biguint,
managed_address, managed_biguint, managed_token_id, rust_biguint,
whitebox_legacy::TxTokenTransfer, DebugApi,
};
use sc_whitelist_module::SCWhitelistModule;
use simple_lock::locked_token::LockedTokenAttributes;

#[test]
fn test_farm_setup() {
Expand Down Expand Up @@ -618,261 +617,3 @@ fn test_farm_through_simple_lock() {
Some(&lp_proxy_token_attributes),
);
}

#[test]
fn test_destroy_farm_through_simple_lock() {
use multiversx_sc::storage::mappers::StorageTokenWrapper;
use simple_lock::locked_token::LockedTokenModule;
use simple_lock::proxy_farm::ProxyFarmModule;
use simple_lock::proxy_farm::*;
use simple_lock::proxy_lp::{LpProxyTokenAttributes, ProxyLpModule};
use simple_lock::SimpleLock;

DebugApi::dummy();
let rust_zero = rust_biguint!(0);
let mut farm_setup = SingleUserFarmSetup::new(farm::contract_obj, pair::contract_obj);
let b_mock = &mut farm_setup.blockchain_wrapper;
let user_addr = farm_setup.user_address.clone();

// setup simple lock SC
let lock_wrapper = b_mock.create_sc_account(
&rust_zero,
Some(&farm_setup.owner_address),
simple_lock::contract_obj,
"Simple Lock Path",
);

let farm_addr = farm_setup.farm_wrapper.address_ref().clone();
let pair_addr = farm_setup.pair_wrapper.address_ref().clone();
b_mock
.execute_tx(&farm_setup.owner_address, &lock_wrapper, &rust_zero, |sc| {
sc.init();
sc.locked_token()
.set_token_id(managed_token_id!(LOCKED_TOKEN_ID));
sc.lp_proxy_token()
.set_token_id(managed_token_id!(LOCKED_LP_TOKEN_ID));
sc.farm_proxy_token()
.set_token_id(managed_token_id!(FARM_PROXY_TOKEN_ID));
sc.add_farm_to_whitelist(
managed_address!(&farm_addr),
managed_token_id!(LP_TOKEN_ID),
FarmType::SimpleFarm,
);
sc.add_lp_to_whitelist(
managed_address!(&pair_addr),
managed_token_id!(WEGLD_TOKEN_ID),
managed_token_id!(MEX_TOKEN_ID),
);
})
.assert_ok();

// change farming token for farm + whitelist simple lock contract
b_mock
.execute_tx(
&farm_setup.owner_address,
&farm_setup.farm_wrapper,
&rust_zero,
|sc| {
sc.farming_token_id().set(&managed_token_id!(LP_TOKEN_ID));
sc.add_sc_address_to_whitelist(managed_address!(lock_wrapper.address_ref()));
},
)
.assert_ok();

b_mock.set_esdt_local_roles(
lock_wrapper.address_ref(),
LOCKED_TOKEN_ID,
&[
EsdtLocalRole::NftCreate,
EsdtLocalRole::NftAddQuantity,
EsdtLocalRole::NftBurn,
],
);
b_mock.set_esdt_local_roles(
lock_wrapper.address_ref(),
LOCKED_LP_TOKEN_ID,
&[
EsdtLocalRole::NftCreate,
EsdtLocalRole::NftAddQuantity,
EsdtLocalRole::NftBurn,
],
);
b_mock.set_esdt_local_roles(
lock_wrapper.address_ref(),
FARM_PROXY_TOKEN_ID,
&[
EsdtLocalRole::NftCreate,
EsdtLocalRole::NftAddQuantity,
EsdtLocalRole::NftBurn,
],
);

b_mock.set_esdt_balance(&user_addr, WEGLD_TOKEN_ID, &rust_biguint!(10_000_000));
b_mock.set_esdt_balance(&user_addr, MEX_TOKEN_ID, &rust_biguint!(10_000_000));

b_mock
.execute_esdt_transfer(
&user_addr,
&lock_wrapper,
MEX_TOKEN_ID,
0,
&rust_biguint!(10_000_000),
|sc| {
sc.lock_tokens_endpoint(15, OptionalValue::None);
},
)
.assert_ok();

b_mock.check_nft_balance(
&user_addr,
LOCKED_TOKEN_ID,
1,
&rust_biguint!(10_000_000),
Some(&LockedTokenAttributes::<DebugApi> {
original_token_id: managed_token_id_wrapped!(MEX_TOKEN_ID),
original_token_nonce: 0,
unlock_epoch: 15,
}),
);

b_mock.set_block_epoch(5);

// add liquidity through simple-lock SC - one locked (XMEX) token, one unlocked (WEGLD)
let transfers = vec![
TxTokenTransfer {
token_identifier: WEGLD_TOKEN_ID.to_vec(),
nonce: 0,
value: rust_biguint!(10_000_000),
},
TxTokenTransfer {
token_identifier: LOCKED_TOKEN_ID.to_vec(),
nonce: 1,
value: rust_biguint!(10_000_000),
},
];
b_mock
.execute_esdt_multi_transfer(&user_addr, &lock_wrapper, &transfers[..], |sc| {
let (dust_first_token, dust_second_token, lp_proxy_payment) = sc
.add_liquidity_locked_token(managed_biguint!(1), managed_biguint!(1))
.into_tuple();

assert_eq!(
dust_first_token.token_identifier,
managed_token_id!(WEGLD_TOKEN_ID)
);
assert_eq!(dust_first_token.token_nonce, 0);
assert_eq!(dust_first_token.amount, managed_biguint!(0));

assert_eq!(
dust_second_token.token_identifier,
managed_token_id!(MEX_TOKEN_ID)
);
assert_eq!(dust_second_token.token_nonce, 0);
assert_eq!(dust_second_token.amount, managed_biguint!(0));

assert_eq!(
lp_proxy_payment.token_identifier,
managed_token_id!(LOCKED_LP_TOKEN_ID)
);
assert_eq!(lp_proxy_payment.token_nonce, 1);
assert_eq!(lp_proxy_payment.amount, managed_biguint!(9_999_000));
})
.assert_ok();

b_mock.check_nft_balance(
&user_addr,
LOCKED_LP_TOKEN_ID,
1,
&rust_biguint!(9_999_000),
Some(&LpProxyTokenAttributes::<DebugApi> {
lp_token_id: managed_token_id!(LP_TOKEN_ID),
first_token_id: managed_token_id!(WEGLD_TOKEN_ID),
first_token_locked_nonce: 0,
second_token_id: managed_token_id!(MEX_TOKEN_ID),
second_token_locked_nonce: 1,
}),
);

b_mock.check_esdt_balance(
lock_wrapper.address_ref(),
LP_TOKEN_ID,
&rust_biguint!(9_999_000),
);

// user enter farm
b_mock
.execute_esdt_transfer(
&user_addr,
&lock_wrapper,
LOCKED_LP_TOKEN_ID,
1,
&rust_biguint!(9_999_000),
|sc| {
let enter_farm_result = sc.enter_farm_locked_token(FarmType::SimpleFarm);
let (out_farm_token, _reward_token) = enter_farm_result.into_tuple();
assert_eq!(
out_farm_token.token_identifier,
managed_token_id!(FARM_PROXY_TOKEN_ID)
);
assert_eq!(out_farm_token.token_nonce, 1);
assert_eq!(out_farm_token.amount, managed_biguint!(9_999_000));
},
)
.assert_ok();

b_mock.check_nft_balance(
&user_addr,
FARM_PROXY_TOKEN_ID,
1,
&rust_biguint!(9_999_000),
Some(&FarmProxyTokenAttributes::<DebugApi> {
farm_type: FarmType::SimpleFarm,
farm_token_id: managed_token_id!(FARM_TOKEN_ID),
farm_token_nonce: 1,
farming_token_id: managed_token_id!(LP_TOKEN_ID),
farming_token_locked_nonce: 1,
}),
);

// user claim farm rewards
// b_mock.set_block_nonce(10);
b_mock.set_block_epoch(10);

b_mock
.execute_esdt_transfer(
&user_addr,
&lock_wrapper,
FARM_PROXY_TOKEN_ID,
1,
&rust_biguint!(9_999_000),
|sc| {
let claim_result =
sc.destroy_farm_locked_tokens(managed_biguint!(1), managed_biguint!(1));

assert_eq!(
claim_result.first_payment.token_identifier,
managed_token_id!(WEGLD_TOKEN_ID)
);
assert_eq!(
claim_result.first_payment.amount,
managed_biguint!(9_999_000)
);

assert_eq!(
claim_result.second_payment.token_identifier,
managed_token_id!(LOCKED_TOKEN_ID)
);
assert_eq!(
claim_result.second_payment.amount,
managed_biguint!(9_999_000)
);

assert_eq!(
claim_result.farm_rewards.token_identifier,
managed_token_id!(MEX_TOKEN_ID)
);
assert_eq!(claim_result.farm_rewards.amount, managed_biguint!(0));
},
)
.assert_ok();
}
4 changes: 3 additions & 1 deletion dex/router/src/multi_pair_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub trait MultiPairSwap:
{
#[payable("*")]
#[endpoint(multiPairSwap)]
fn multi_pair_swap(&self, swap_operations: MultiValueEncoded<SwapOperationType<Self::Api>>) {
fn multi_pair_swap(&self, swap_operations: MultiValueEncoded<SwapOperationType<Self::Api>>) -> ManagedVec<EsdtTokenPayment> {
require!(self.is_active(), "Not active");

let (token_id, nonce, amount) = self.call_value().single_esdt().into_tuple();
Expand Down Expand Up @@ -67,6 +67,8 @@ pub trait MultiPairSwap:

payments.push(last_payment);
self.send().direct_multi(&caller, &payments);

payments
}

fn actual_swap_fixed_input(
Expand Down
86 changes: 0 additions & 86 deletions locked-asset/proxy_dex/src/proxy_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@ pub type EnterFarmProxyResultType<M> = MultiValue2<EsdtTokenPayment<M>, EsdtToke
pub type ExitFarmProxyResultType<M> = MultiValue2<EsdtTokenPayment<M>, EsdtTokenPayment<M>>;
pub type ClaimRewardsFarmProxyResultType<M> = MultiValue2<EsdtTokenPayment<M>, EsdtTokenPayment<M>>;

#[derive(TypeAbi, TopEncode, TopDecode, NestedEncode, NestedDecode)]
pub struct DestroyFarmResultType<M: ManagedTypeApi> {
pub first_payment: EsdtTokenPayment<M>,
pub second_payment: EsdtTokenPayment<M>,
pub farm_rewards: EsdtTokenPayment<M>,
}

#[multiversx_sc::module]
pub trait ProxyFarmModule:
crate::proxy_common::ProxyCommonModule
Expand Down Expand Up @@ -241,85 +234,6 @@ pub trait ProxyFarmModule:
(initial_proxy_farming_tokens, exit_result.reward_tokens).into()
}

#[payable("*")]
#[endpoint(destroyFarmProxy)]
fn destroy_farm_proxy(
&self,
farm_address: ManagedAddress,
pair_address: ManagedAddress,
first_token_amount_min: BigUint,
second_token_amount_min: BigUint,
opt_original_caller: OptionalValue<ManagedAddress>,
) -> DestroyFarmResultType<Self::Api> {
self.require_is_intermediated_farm(&farm_address);
self.require_is_intermediated_pair(&pair_address);
self.require_wrapped_farm_token_id_not_empty();
self.require_wrapped_lp_token_id_not_empty();

let wrapped_farm_token_mapper = self.wrapped_farm_token();
let payment = self.call_value().single_esdt();
wrapped_farm_token_mapper.require_same_token(&payment.token_identifier);

let full_wrapped_farm_attributes: WrappedFarmTokenAttributes<Self::Api> = self
.blockchain()
.get_token_attributes(&payment.token_identifier, payment.token_nonce);

let wrapped_farm_attributes_for_exit: WrappedFarmTokenAttributes<Self::Api> =
full_wrapped_farm_attributes.into_part(&payment.amount);

let caller = self.blockchain().get_caller();
let original_caller = self.get_orig_caller_from_opt(&caller, opt_original_caller);

let exit_result = self.call_exit_farm(
original_caller.clone(),
farm_address.clone(),
wrapped_farm_attributes_for_exit.farm_token.clone(),
);

self.burn_if_base_asset(&exit_result.farming_tokens);

let wrapped_farm_tokens_for_initial_tokens = WrappedFarmToken {
payment: payment.clone(),
attributes: wrapped_farm_attributes_for_exit.clone(),
};

let initial_proxy_farming_tokens = self
.handle_farm_penalty_and_get_output_proxy_farming_token(
&original_caller,
wrapped_farm_tokens_for_initial_tokens,
exit_result.farming_tokens.amount,
);

let mut remove_liquidity_result = self.remove_liquidity_proxy_common(
initial_proxy_farming_tokens.clone(),
pair_address,
first_token_amount_min,
second_token_amount_min,
);

// Burn farm token
wrapped_farm_token_mapper.nft_burn(payment.token_nonce, &payment.amount);

// Push farm rewards
remove_liquidity_result.push(exit_result.reward_tokens.clone());

self.send_multiple_tokens_if_not_zero(&caller, &remove_liquidity_result);

self.emit_exit_farm_proxy_event(
&original_caller,
&farm_address,
payment,
wrapped_farm_attributes_for_exit,
exit_result.reward_tokens.clone(),
);

DestroyFarmResultType {
first_payment: remove_liquidity_result.get(0),
second_payment: remove_liquidity_result.get(1),
farm_rewards: exit_result.reward_tokens,
}
}

fn handle_farm_penalty_and_get_output_proxy_farming_token(
&self,
caller: &ManagedAddress,
Expand Down
Loading

0 comments on commit b542ecd

Please sign in to comment.