Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: enable lm claim rewards #963

Merged
merged 11 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "runtime-integration-tests"
version = "1.25.4"
version = "1.26.0"
description = "Integration tests"
authors = ["GalacticCouncil"]
edition = "2021"
Expand Down
1 change: 0 additions & 1 deletion integration-tests/src/call_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use frame_support::{
assert_ok,
sp_runtime::{FixedU128, Permill},
traits::{Contains, StorePreimage},
weights::Weight,
};
use hydradx_runtime::{origins, Preimage};
use polkadot_xcm::v3::prelude::*;
Expand Down
143 changes: 140 additions & 3 deletions integration-tests/src/omnipool_liquidity_mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,12 @@ fn withdraw_shares_should_work_when_deposit_exists() {
);

set_relaychain_block_number(700);
//Arrange - claim before withdraw
assert_ok!(hydradx_runtime::OmnipoolLiquidityMining::claim_rewards(
RuntimeOrigin::signed(CHARLIE.into()),
deposit_id,
yield_farm_1_id
),);

let charlie_hdx_balance_0 = hydradx_runtime::Currencies::free_balance(HDX, &CHARLIE.into());
//Act 2 - claim and withdraw should in the same period should work.
Expand All @@ -625,9 +631,12 @@ fn withdraw_shares_should_work_when_deposit_exists() {
));

//Assert
//NOTE: withdraw shares claims rewards automatically
let charlie_new_hdx_balance = hydradx_runtime::Currencies::free_balance(HDX, &CHARLIE.into());
assert!(charlie_new_hdx_balance > charlie_hdx_balance_0);
//NOTE: claim happened before withdraw in this period so no rewards should be claimed.

assert_eq!(
hydradx_runtime::Currencies::free_balance(HDX, &CHARLIE.into()),
charlie_hdx_balance_0
);

//NOTE: last shares were unlockend and deposit's nft should be destroyed and omnipool's
//position should be unlocked.
Expand Down Expand Up @@ -1411,6 +1420,134 @@ fn liquidity_mining_should_work_when_farm_distribute_bonds() {
});
}

#[test]
fn claim_rewards_should_work_when_farm_is_updated() {
TestNet::reset();

Hydra::execute_with(|| {
let global_farm_1_id = 1;
let yield_farm_1_id = 2;
let yield_farm_2_id = 3;

//Arrange
init_omnipool();
seed_lm_pot();
//necessary for oracle to have a price.
do_lrna_hdx_trade();

//NOTE: necessary to get oracle price.
hydradx_run_to_block(100);
set_relaychain_block_number(100);
create_global_farm(None, None);

set_relaychain_block_number(200);
create_yield_farm(global_farm_1_id, ETH);
create_yield_farm(global_farm_1_id, DOT);

set_relaychain_block_number(300);

assert_ok!(hydradx_runtime::Currencies::update_balance(
hydradx_runtime::RuntimeOrigin::root(),
CHARLIE.into(),
ETH,
10_000 * UNITS as i128,
));

let position_id = omnipool_add_liquidity(CHARLIE.into(), ETH, 1_000 * UNITS);
assert_nft_owner!(
hydradx_runtime::OmnipoolCollectionId::get(),
position_id,
CHARLIE.into()
);

set_relaychain_block_number(400);
let deposit_id = 1;
assert_ok!(hydradx_runtime::OmnipoolLiquidityMining::deposit_shares(
RuntimeOrigin::signed(CHARLIE.into()),
global_farm_1_id,
yield_farm_1_id,
position_id
));

set_relaychain_block_number(500);
assert_ok!(hydradx_runtime::Currencies::update_balance(
hydradx_runtime::RuntimeOrigin::root(),
CHARLIE.into(),
DOT,
10_000 * UNITS as i128,
));

let position_id = omnipool_add_liquidity(CHARLIE.into(), DOT, UNITS);
assert_nft_owner!(
hydradx_runtime::OmnipoolCollectionId::get(),
position_id,
CHARLIE.into()
);

set_relaychain_block_number(550);
let deposit_id_2 = 2;
assert_ok!(hydradx_runtime::OmnipoolLiquidityMining::deposit_shares(
RuntimeOrigin::signed(CHARLIE.into()),
global_farm_1_id,
yield_farm_2_id,
position_id
));

//Act - update farm
let planned_yielding_periods: BlockNumber = 2_000_000_u32;
let yield_per_period = Perquintill::from_parts(550_776_255_707);
let min_deposit = 5_000;
assert_ok!(hydradx_runtime::OmnipoolLiquidityMining::update_global_farm(
RuntimeOrigin::root(),
global_farm_1_id,
planned_yielding_periods,
yield_per_period,
min_deposit
));
//Assert
let g_farm =
warehouse_liquidity_mining::GlobalFarm::<hydradx_runtime::Runtime, Instance1>::get(global_farm_1_id)
.unwrap();
assert_eq!(g_farm.planned_yielding_periods, planned_yielding_periods);
assert_eq!(g_farm.yield_per_period, yield_per_period);
assert_eq!(g_farm.min_deposit, min_deposit);

let charlie_hdx_balance_0 = hydradx_runtime::Currencies::free_balance(HDX, &CHARLIE.into());
//Act 1 - claim rewards for 2-nd yield-farm-entry
set_relaychain_block_number(600);
assert_ok!(hydradx_runtime::OmnipoolLiquidityMining::claim_rewards(
RuntimeOrigin::signed(CHARLIE.into()),
deposit_id_2,
yield_farm_2_id
));

//Assert
//NOTE: can't assert state in the deposit because fields are private
let charlie_new_hdx_balance_after_first_claim = hydradx_runtime::Currencies::free_balance(HDX, &CHARLIE.into());
assert!(
charlie_new_hdx_balance_after_first_claim > charlie_hdx_balance_0,
"Charlie's balance should be increased"
);
assert_eq!(charlie_new_hdx_balance_after_first_claim, 1000030740535405);

//Act 2 - claim rewards for differnt yield-farm-entry in the same period should work.
assert_ok!(hydradx_runtime::OmnipoolLiquidityMining::claim_rewards(
RuntimeOrigin::signed(CHARLIE.into()),
deposit_id,
yield_farm_1_id
));

//Assert
//NOTE: can't assert state in the deposit because fields are private
let charlie_new_hdx_balance_after_2nd_claim = hydradx_runtime::Currencies::free_balance(HDX, &CHARLIE.into());
assert!(
charlie_new_hdx_balance_after_2nd_claim > charlie_new_hdx_balance_after_first_claim,
"Charlie's balance should be increased"
);
assert_eq!(charlie_new_hdx_balance_after_2nd_claim, 1000031130694537);
});
}

pub fn expect_reward_claimed_events(e: Vec<RuntimeEvent>) {
let last_events = test_utils::last_events::<hydradx_runtime::RuntimeEvent, hydradx_runtime::Runtime>(10);

Expand Down
23 changes: 16 additions & 7 deletions integration-tests/src/xyk_liquidity_mining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,8 +624,10 @@ fn withdraw_shares_should_work_when_deposit_exists() {

//Assert
//NOTE: withdraw is claiming rewards automatically
let dave_hdx_0 = hydradx_runtime::Currencies::free_balance(HDX, &DAVE.into());
assert_eq!(dave_hdx_0, 1_004_254_545_454_545_u128);
assert_eq!(
hydradx_runtime::Currencies::free_balance(HDX, &DAVE.into()),
1_004_254_545_454_545_u128
);

//NOTE: shares should not be unlocked because deposit wasn't destroyed(it has 1
//yield-farm-entry left)
Expand All @@ -645,8 +647,14 @@ fn withdraw_shares_should_work_when_deposit_exists() {
);

set_relaychain_block_number(700);
//Arrange - claim before withdraw
assert_ok!(XYKLiquidityMining::claim_rewards(
RuntimeOrigin::signed(DAVE.into()),
deposit_id,
yield_farm_1_id,
));

//Act 2
//Act 2 - claim and withdraw in the same period should work.
assert_ok!(XYKLiquidityMining::withdraw_shares(
RuntimeOrigin::signed(DAVE.into()),
deposit_id,
Expand All @@ -655,10 +663,11 @@ fn withdraw_shares_should_work_when_deposit_exists() {
));

//Assert
//withdraw_shares claims rewards under the hood
let dave_hdx_1 = hydradx_runtime::Currencies::free_balance(HDX, &DAVE.into());

assert!(dave_hdx_1 > dave_hdx_0);
//NOTE: claim happened before withdraw in this period so no rewards should be claimed.
assert_eq!(
hydradx_runtime::Currencies::free_balance(HDX, &DAVE.into()),
1_021_616_083_916_083_u128
);

//NOTE: last shares were unlockend and deposit's nft should be destroyed and omnipool's
//position should be unlocked.
Expand Down
2 changes: 1 addition & 1 deletion pallets/liquidity-mining/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pallet-liquidity-mining"
version = "4.4.3"
version = "4.4.4"
description = "Liquidity mining"
authors = ["GalacticCouncil"]
edition = "2021"
Expand Down
33 changes: 33 additions & 0 deletions pallets/liquidity-mining/src/tests/update_global_farm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,36 @@ fn update_global_farm_should_fail_when_yield_period_is_zero() {
});
});
}

#[test]
fn claim_rewards_should_work_after_update_global_farm() {
predefined_test_ext_with_deposits().execute_with(|| {
let _ = with_transaction(|| {
//Arrange
let planned_yielding_periods: BlockNumber = 1_000u64;
let yield_per_period = Perquintill::from_percent(20);
let min_deposit = 20_000;

set_block_number(100_000);

//Act
assert_ok!(LiquidityMining::update_global_farm(
GC_FARM,
planned_yielding_periods,
yield_per_period,
min_deposit,
));

set_block_number(1_000_000);

//Assert
assert_eq!(
LiquidityMining::claim_rewards(ALICE, PREDEFINED_DEPOSIT_IDS[0], GC_BSX_TKN1_YIELD_FARM_ID, false)
.unwrap(),
(GC_FARM, BSX, 28495477087879389002, 142022912120610998)
);

TransactionOutcome::Commit(DispatchResult::Ok(()))
});
});
}
2 changes: 1 addition & 1 deletion pallets/omnipool-liquidity-mining/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pallet-omnipool-liquidity-mining"
version = "2.4.1"
version = "2.5.0"
authors = ['GalacticCouncil']
edition = "2021"
license = "Apache-2.0"
Expand Down
6 changes: 1 addition & 5 deletions pallets/omnipool-liquidity-mining/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,12 +576,8 @@ benchmarks! {

set_period::<T>(400);

}: {
//We fire and forget as claim rewards is disabled
let _ = crate::Pallet::<T>::claim_rewards(RawOrigin::Signed(lp1).into(), deposit_id, 10);
} verify {
}: _(RawOrigin::Signed(lp1), deposit_id, 10)

}

withdraw_shares {
let owner = create_funded_account::<T>("owner", 0, G_FARM_TOTAL_REWARDS, REWARD_CURRENCY.into());
Expand Down
29 changes: 20 additions & 9 deletions pallets/omnipool-liquidity-mining/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,9 +311,6 @@ pub mod pallet {
/// Oracle providing `price_adjustment` could not be found for requested assets.
PriceAdjustmentNotAvailable,

/// The extrinsic is disabled for now.
Disabled,

/// No farms specified to join
NoFarmEntriesSpecified,
}
Expand Down Expand Up @@ -747,8 +744,6 @@ pub mod pallet {
Ok(())
}

/// Note: This extrinsic is disabled
///
/// Claim rewards from liquidity mining program for deposit represented by the `deposit_id`.
///
/// This function calculate user rewards from liquidity mining and transfer rewards to `origin`
Expand All @@ -764,11 +759,27 @@ pub mod pallet {
#[pallet::call_index(10)]
#[pallet::weight(<T as Config>::WeightInfo::claim_rewards())]
pub fn claim_rewards(
_origin: OriginFor<T>,
_deposit_id: DepositId,
_yield_farm_id: YieldFarmId,
origin: OriginFor<T>,
deposit_id: DepositId,
yield_farm_id: YieldFarmId,
) -> DispatchResult {
return Err(Error::<T>::Disabled.into());
let owner = Self::ensure_nft_owner(origin, deposit_id)?;

let (global_farm_id, reward_currency, claimed, _) =
T::LiquidityMiningHandler::claim_rewards(owner.clone(), deposit_id, yield_farm_id)?;

ensure!(!claimed.is_zero(), Error::<T>::ZeroClaimedRewards);

Self::deposit_event(Event::RewardClaimed {
global_farm_id,
yield_farm_id,
who: owner,
claimed,
reward_currency,
deposit_id,
});

Ok(())
}

/// This function claim rewards and withdraw LP shares from yield farm. Omnipool position
Expand Down
Loading
Loading