Skip to content

Commit

Permalink
added unit test for unstake endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
psorinionut committed Jun 27, 2024
1 parent c2a140a commit abf386a
Show file tree
Hide file tree
Showing 10 changed files with 1,255 additions and 60 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions legacy-contracts/farm-staking-proxy-legacy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,36 @@ path = "../../common/modules/token_merge_helper"
[dependencies.common_structs]
path = "../../common/common_structs"

[dependencies.farm-staking]
path = "../../farm-staking/farm-staking"

[dependencies.pair]
path = "../../dex/pair"

[dependencies.farm-with-locked-rewards]
path = "../../dex/farm-with-locked-rewards"

[dev-dependencies.energy-factory]
path = "../../locked-asset/energy-factory"

[dev-dependencies.energy-query]
path = "../../energy-integration/common-modules/energy-query"

[dev-dependencies.simple-lock]
path = "../../locked-asset/simple-lock"

[dev-dependencies.farm_token]
path = "../../common/modules/farm/farm_token"

[dev-dependencies.locking_module]
path = "../../common/modules/locking_module"

[dev-dependencies.pausable]
path = "../../common/modules/pausable"

[dev-dependencies.sc_whitelist_module]
path = "../../common/modules/sc_whitelist_module"

[dev-dependencies]
num-bigint = "0.4.2"
num-traits = "0.2"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,13 @@
multiversx_sc::imports!();

use common_structs::{RawResultWrapper, RawResultsType};
use farm_staking::unstake_farm::ProxyTrait as _;
use multiversx_sc::storage::StorageKey;
use pair::{pair_actions::remove_liq::ProxyTrait as _, safe_price_view::ProxyTrait as _};

use crate::result_types::*;

mod farm_proxy {
multiversx_sc::imports!();

#[multiversx_sc::proxy]
pub trait FarmProxy {
#[payable("*")]
#[endpoint(exitFarm)]
fn exit_farm(&self) -> MultiValue2<EsdtTokenPayment, EsdtTokenPayment>;

#[view(getFarmingTokenId)]
fn farming_token_id(&self) -> TokenIdentifier;
}
}

mod farm_staking_proxy {
multiversx_sc::imports!();

#[multiversx_sc::proxy]
pub trait FarmStakingProxy {
#[payable("*")]
#[endpoint(unstakeFarmThroughProxy)]
fn unstake_farm_through_proxy(
&self,
original_caller: ManagedAddress,
) -> MultiValue2<EsdtTokenPayment, EsdtTokenPayment>;
}
}

mod pair_proxy {
multiversx_sc::imports!();

#[multiversx_sc::proxy]
pub trait PairProxy {
#[payable("*")]
#[endpoint(removeLiquidity)]
fn remove_liquidity(
&self,
first_token_amount_min: BigUint,
second_token_amount_min: BigUint,
) -> MultiValue2<EsdtTokenPayment, EsdtTokenPayment>;

#[endpoint(updateAndGetTokensForGivenPositionWithSafePrice)]
fn update_and_get_tokens_for_given_position_with_safe_price(
&self,
liquidity: BigUint,
) -> MultiValue2<EsdtTokenPayment, EsdtTokenPayment>;
}
}
pub static FARMING_TOKEN_STORAGE_KEY: &[u8] = b"farming_token_id";

#[multiversx_sc::module]
pub trait ExternalContractsInteractionsModule:
Expand All @@ -61,14 +17,15 @@ pub trait ExternalContractsInteractionsModule:

fn lp_farm_exit(
&self,
orig_caller: ManagedAddress,
lp_farm_token_nonce: u64,
lp_farm_token_amount: BigUint,
) -> LpFarmExitResult<Self::Api> {
let lp_farm_token_id = self.lp_farm_token_id().get();
let lp_farm_address = self.lp_farm_address().get();
let raw_results: RawResultsType<Self::Api> = self
.lp_farm_proxy_obj(lp_farm_address)
.exit_farm()
.exit_farm_endpoint(OptionalValue::Some(orig_caller))
.with_esdt_transfer((lp_farm_token_id, lp_farm_token_nonce, lp_farm_token_amount))
.execute_on_dest_context();

Expand All @@ -93,9 +50,13 @@ pub trait ExternalContractsInteractionsModule:

fn get_lp_farming_token_identifier(&self) -> TokenIdentifier {
let lp_farm_address = self.lp_farm_address().get();
self.lp_farm_proxy_obj(lp_farm_address)
.farming_token_id()
.execute_on_dest_context()

let farming_token_mapper = SingleValueMapper::<_, _, ManagedAddress>::new_from_address(
lp_farm_address,
StorageKey::new(FARMING_TOKEN_STORAGE_KEY),
);

farming_token_mapper.get()
}

// staking farm
Expand Down Expand Up @@ -201,16 +162,16 @@ pub trait ExternalContractsInteractionsModule:
// proxies

#[proxy]
fn staking_farm_proxy_obj(
&self,
sc_address: ManagedAddress,
) -> farm_staking_proxy::Proxy<Self::Api>;
fn staking_farm_proxy_obj(&self, sc_address: ManagedAddress) -> farm_staking::Proxy<Self::Api>;

#[proxy]
fn lp_farm_proxy_obj(&self, sc_address: ManagedAddress) -> farm_proxy::Proxy<Self::Api>;
fn lp_farm_proxy_obj(
&self,
sc_address: ManagedAddress,
) -> farm_with_locked_rewards::Proxy<Self::Api>;

#[proxy]
fn pair_proxy_obj(&self, sc_address: ManagedAddress) -> pair_proxy::Proxy<Self::Api>;
fn pair_proxy_obj(&self, sc_address: ManagedAddress) -> pair::Proxy<Self::Api>;

// storage

Expand Down
7 changes: 5 additions & 2 deletions legacy-contracts/farm-staking-proxy-legacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,11 @@ pub trait FarmStakingProxy:
let attributes = self.get_dual_yield_token_attributes(payment_nonce);
let lp_farm_token_amount =
self.get_lp_farm_token_amount_equivalent(&attributes, &payment_amount);
let lp_farm_exit_result =
self.lp_farm_exit(attributes.lp_farm_token_nonce, lp_farm_token_amount);
let lp_farm_exit_result = self.lp_farm_exit(
caller.clone(),
attributes.lp_farm_token_nonce,
lp_farm_token_amount,
);

let remove_liq_result = self.pair_remove_liquidity(
lp_farm_exit_result.lp_tokens,
Expand Down
48 changes: 48 additions & 0 deletions legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Pair constants

pub const PAIR_WASM_PATH: &'static str = "pair/output/pair.wasm";

Check warning on line 3 in legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs#L3

warning: constants have by default a `'static` lifetime --> legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs:3:28 | 3 | pub const PAIR_WASM_PATH: &'static str = "pair/output/pair.wasm"; | -^^^^^^^---- help: consider removing `'static`: `&str` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes = note: `#[warn(clippy::redundant_static_lifetimes)]` on by default
Raw output
legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs:3:28:w:warning: constants have by default a `'static` lifetime
 --> legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs:3:28
  |
3 | pub const PAIR_WASM_PATH: &'static str = "pair/output/pair.wasm";
  |                           -^^^^^^^---- help: consider removing `'static`: `&str`
  |
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
  = note: `#[warn(clippy::redundant_static_lifetimes)]` on by default


__END__
pub const WEGLD_TOKEN_ID: &[u8] = b"WEGLD-abcdef";
pub const RIDE_TOKEN_ID: &[u8] = b"RIDE-abcdef";
pub const LP_TOKEN_ID: &[u8] = b"LPTOK-abcdef"; // also farming token ID for LP farm

pub const USER_TOTAL_WEGLD_TOKENS: u64 = 2_000_000_000;
pub const USER_TOTAL_RIDE_TOKENS: u64 = 2_000_000_000;
pub const USER_TOTAL_LP_TOKENS: u64 = 1_001_000_000;

pub const BLOCK_NONCE_FIRST_ADD_LIQ: u64 = 5;
pub const BLOCK_NONCE_SECOND_ADD_LIQ: u64 = 6;
pub const BLOCK_NONCE_AFTER_PAIR_SETUP: u64 = 100;

// LP farm constants

pub const FARM_WASM_PATH: &'static str = "farm/output/farm.wasm";

Check warning on line 18 in legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs#L18

warning: constants have by default a `'static` lifetime --> legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs:18:28 | 18 | pub const FARM_WASM_PATH: &'static str = "farm/output/farm.wasm"; | -^^^^^^^---- help: consider removing `'static`: `&str` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
Raw output
legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs:18:28:w:warning: constants have by default a `'static` lifetime
  --> legacy-contracts/farm-staking-proxy-legacy/tests/constants/mod.rs:18:28
   |
18 | pub const FARM_WASM_PATH: &'static str = "farm/output/farm.wasm";
   |                           -^^^^^^^---- help: consider removing `'static`: `&str`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes


__END__
pub const LP_FARM_TOKEN_ID: &[u8] = b"LPFARM-abcdef";
pub const DIVISION_SAFETY_CONSTANT: u64 = 1_000_000_000_000;
pub const MIN_FARMING_EPOCHS: u8 = 2;
pub const PENALTY_PERCENT: u64 = 10;
pub const LP_FARM_PER_BLOCK_REWARD_AMOUNT: u64 = 5_000;

// Energy factory constants

pub const EPOCHS_IN_YEAR: u64 = 360;
pub static MEX_TOKEN_ID: &[u8] = b"MEX-123456";
pub static LOCKED_TOKEN_ID: &[u8] = b"LOCKED-123456";
pub static LEGACY_LOCKED_TOKEN_ID: &[u8] = b"LEGACY-123456";
pub static LOCK_OPTIONS: &[u64] = &[EPOCHS_IN_YEAR, 5 * EPOCHS_IN_YEAR, 10 * EPOCHS_IN_YEAR]; // 1, 5 or 10 years
pub static PENALTY_PERCENTAGES: &[u64] = &[4_000, 6_000, 8_000];

// Staking farm constants

pub const STAKING_FARM_WASM_PATH: &str = "farm-staking/output/farm-staking.wasm";
pub const STAKING_REWARD_TOKEN_ID: &[u8] = RIDE_TOKEN_ID;
pub const STAKING_TOKEN_ID: &[u8] = RIDE_TOKEN_ID;
pub const STAKING_FARM_TOKEN_ID: &[u8] = b"STKFARM-abcdef";
pub const MAX_APR: u64 = 5_000; // 50%
pub const UNBOND_EPOCHS: u64 = 10;
pub const STAKING_FARM_PER_BLOCK_REWARD_AMOUNT: u64 = 1_000;
pub const REWARD_CAPACITY: u64 = 1_000_000_000_000;

// Proxy constants

pub const PROXY_WASM_PATH: &str = "farm-staking-proxy/output/farm-staking-proxy";
pub const DUAL_YIELD_TOKEN_ID: &[u8] = b"DYIELD-abcdef";
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#![allow(deprecated)]

pub mod constants;
pub mod staking_farm_with_lp_external_contracts;
pub mod staking_farm_with_lp_staking_contract_interactions;
pub mod staking_farm_with_lp_staking_contract_setup;

multiversx_sc::imports!();

use common_structs::FarmTokenAttributes;
use constants::*;
use farm_staking_proxy_legacy::dual_yield_token::DualYieldTokenAttributes;

use farm_staking::stake_farm::StakeFarmModule;
use farm_with_locked_rewards::Farm;
use multiversx_sc_scenario::{
imports::TxTokenTransfer, managed_address, managed_biguint, rust_biguint, DebugApi,
};
use pair::pair_actions::add_liq::AddLiquidityModule;
use staking_farm_with_lp_staking_contract_interactions::*;

#[test]
fn test_all_setup() {
let _ = FarmStakingSetup::new(
pair::contract_obj,
farm_with_locked_rewards::contract_obj,
energy_factory::contract_obj,
farm_staking::contract_obj,
farm_staking_proxy_legacy::contract_obj,
);
}

#[test]
fn test_unstake_from_legacy_proxy() {
let mut setup = FarmStakingSetup::new(
pair::contract_obj,
farm_with_locked_rewards::contract_obj,
energy_factory::contract_obj,
farm_staking::contract_obj,
farm_staking_proxy_legacy::contract_obj,
);

DebugApi::dummy();
setup
.b_mock
.set_block_nonce(BLOCK_NONCE_AFTER_PAIR_SETUP + 20);
setup.b_mock.set_block_epoch(20);

let token_amount = 1_000_000_000u64;

let payments = vec![
TxTokenTransfer {
token_identifier: WEGLD_TOKEN_ID.to_vec(),
nonce: 0,
value: rust_biguint!(token_amount),
},
TxTokenTransfer {
token_identifier: RIDE_TOKEN_ID.to_vec(),
nonce: 0,
value: rust_biguint!(token_amount),
},
];
setup
.b_mock
.execute_esdt_multi_transfer(&setup.user_addr, &setup.pair_wrapper, &payments, |sc| {
sc.add_liquidity(managed_biguint!(1u64), managed_biguint!(1u64));
})
.assert_ok();

setup
.b_mock
.execute_esdt_transfer(
&setup.user_addr,
&setup.lp_farm_wrapper,
LP_TOKEN_ID,
0,
&rust_biguint!(token_amount),
|sc| {
sc.enter_farm_endpoint(OptionalValue::None);
},
)
.assert_ok();

// Simulate enter proxy staking contract
let lp_farm_token_attributes: FarmTokenAttributes<DebugApi> = FarmTokenAttributes {
reward_per_share: managed_biguint!(0),
entering_epoch: 20,
compounded_reward: managed_biguint!(0),
current_farm_amount: managed_biguint!(token_amount),
original_owner: managed_address!(&setup.user_addr),
};
setup.b_mock.set_nft_balance(
setup.proxy_wrapper.address_ref(),
LP_FARM_TOKEN_ID,
1,
&rust_biguint!(token_amount),
&lp_farm_token_attributes,
);
setup.b_mock.set_esdt_balance(
setup.proxy_wrapper.address_ref(),
RIDE_TOKEN_ID,
&rust_biguint!(token_amount),
);

setup
.b_mock
.execute_tx(
setup.proxy_wrapper.address_ref(),
&setup.staking_farm_wrapper,
&rust_biguint!(0u64),
|sc| {
sc.stake_farm_through_proxy(
managed_biguint!(token_amount),
managed_address!(&setup.user_addr),
);
},
)
.assert_ok();

let dual_yield_token_amount = token_amount;
let dual_yield_token_attributes: DualYieldTokenAttributes<DebugApi> =
DualYieldTokenAttributes {
lp_farm_token_nonce: 1,
lp_farm_token_amount: managed_biguint!(dual_yield_token_amount),
staking_farm_token_nonce: 1,
staking_farm_token_amount: managed_biguint!(dual_yield_token_amount),
};
setup.b_mock.set_nft_balance(
&setup.user_addr,
DUAL_YIELD_TOKEN_ID,
1,
&rust_biguint!(dual_yield_token_amount),
&dual_yield_token_attributes,
);

let expected_token_amount = 990_000_000u64;
setup.unstake_proxy(
1,
dual_yield_token_amount,
expected_token_amount,
0,
0,
expected_token_amount,
30,
);

setup.b_mock.set_block_epoch(30);
setup.unbond_proxy(2, expected_token_amount, expected_token_amount);
}
Loading

0 comments on commit abf386a

Please sign in to comment.