diff --git a/pallets/farming/src/gauge.rs b/pallets/farming/src/gauge.rs index 761421633..e2dca1426 100644 --- a/pallets/farming/src/gauge.rs +++ b/pallets/farming/src/gauge.rs @@ -69,7 +69,7 @@ pub struct GaugePoolInfo, - pub coefficient: Perbill, + pub gauge_basic_rewards: BTreeMap, pub max_block: BlockNumberFor, pub gauge_amount: BalanceOf, pub total_time_factor: u128, @@ -95,7 +95,7 @@ where token: CurrencyIdOf, keeper: AccountIdOf, reward_issuer: AccountIdOf, - coefficient: Perbill, + gauge_basic_rewards: BTreeMap, max_block: BlockNumberFor, current_block_number: BlockNumberFor, ) -> Self { @@ -105,7 +105,7 @@ where keeper, reward_issuer, rewards: BTreeMap::new(), - coefficient, + gauge_basic_rewards, max_block, gauge_amount: Default::default(), total_time_factor: Default::default(), @@ -124,7 +124,7 @@ where pid: PoolId, pool_info: &mut PoolInfo, CurrencyIdOf, AccountIdOf, BlockNumberFor>, gauge_token: CurrencyIdOf, - coefficient: Perbill, + gauge_basic_rewards: BTreeMap, BalanceOf>, max_block: BlockNumberFor, ) -> DispatchResult { let gid = Self::gauge_pool_next_id(); @@ -135,7 +135,7 @@ where gauge_token, pool_info.keeper.clone(), pool_info.reward_issuer.clone(), - coefficient, + gauge_basic_rewards, max_block, current_block_number, ); @@ -294,10 +294,10 @@ where let reward = reward_amount .checked_sub(&total_gauged_reward) .ok_or(ArithmeticError::Overflow)?; - // gauge_reward = gauge rate * gauge coefficient * existing rewards in the + // gauge_reward = gauge rate * gauge rewards * existing rewards in the // gauge pool let gauge_reward = gauge_rate * reward; - // reward_to_claim = farming rate * gauge rate * gauge coefficient * + // reward_to_claim = farming rate * gauge rate * gauge rewards * // existing rewards in the gauge pool let reward_to_claim: BalanceOf = U256::from(share_info.share.to_owned().saturated_into::()) @@ -432,10 +432,10 @@ where let reward = reward_amount .checked_sub(&total_gauged_reward) .ok_or(ArithmeticError::Overflow)?; - // gauge_reward = gauge rate * gauge coefficient * existing rewards in the + // gauge_reward = gauge rate * gauge rewards * existing rewards in the // gauge pool let gauge_reward = gauge_rate * reward; - // reward_to_claim = farming rate * gauge rate * gauge coefficient * + // reward_to_claim = farming rate * gauge rate * gauge rewards * // existing rewards in the gauge pool let reward_to_claim: BalanceOf = U256::from(share_info.share.to_owned().saturated_into::()) diff --git a/pallets/farming/src/lib.rs b/pallets/farming/src/lib.rs index 9b18703a1..b8d132967 100644 --- a/pallets/farming/src/lib.rs +++ b/pallets/farming/src/lib.rs @@ -261,22 +261,18 @@ pub mod pallet { GaugePoolInfos::::iter().for_each( |(gid, mut gauge_pool_info)| match gauge_pool_info.gauge_state { GaugeState::Bonded => { - if let Some(pool_info) = Self::pool_infos(&gauge_pool_info.pid) { - pool_info.basic_rewards.clone().iter().for_each( - |(reward_currency_id, reward_amount)| { - gauge_pool_info - .rewards - .entry(*reward_currency_id) - .and_modify(|(total_reward, _, _)| { - *total_reward = total_reward.saturating_add( - gauge_pool_info.coefficient * *reward_amount, - ); - }) - .or_insert((*reward_amount, Zero::zero(), Zero::zero())); - }, - ); - GaugePoolInfos::::insert(gid, &gauge_pool_info); - } + gauge_pool_info.gauge_basic_rewards.clone().iter().for_each( + |(reward_currency_id, reward_amount)| { + gauge_pool_info + .rewards + .entry(*reward_currency_id) + .and_modify(|(total_reward, _, _)| { + *total_reward = total_reward.saturating_add(*reward_amount); + }) + .or_insert((*reward_amount, Zero::zero(), Zero::zero())); + }, + ); + GaugePoolInfos::::insert(gid, &gauge_pool_info); }, _ => (), }, @@ -298,7 +294,11 @@ pub mod pallet { origin: OriginFor, tokens_proportion: Vec<(CurrencyIdOf, Perbill)>, basic_rewards: Vec<(CurrencyIdOf, BalanceOf)>, - gauge_init: Option<(CurrencyIdOf, Perbill, BlockNumberFor)>, + gauge_init: Option<( + CurrencyIdOf, + BlockNumberFor, + Vec<(CurrencyIdOf, BalanceOf)>, + )>, min_deposit_to_start: BalanceOf, #[pallet::compact] after_block_to_start: BlockNumberFor, #[pallet::compact] withdraw_limit_time: BlockNumberFor, @@ -328,8 +328,17 @@ pub mod pallet { withdraw_limit_count, ); - if let Some((gauge_token, coefficient, max_block)) = gauge_init { - Self::create_gauge_pool(pid, &mut pool_info, gauge_token, coefficient, max_block)?; + if let Some((gauge_token, max_block, gauge_basic_rewards)) = gauge_init { + let gauge_basic_rewards_map: BTreeMap, BalanceOf> = + gauge_basic_rewards.into_iter().map(|(k, v)| (k, v)).collect(); + + Self::create_gauge_pool( + pid, + &mut pool_info, + gauge_token, + gauge_basic_rewards_map, + max_block, + )?; }; PoolInfos::::insert(pid, &pool_info); @@ -555,7 +564,11 @@ pub mod pallet { withdraw_limit_time: Option>, claim_limit_time: Option>, withdraw_limit_count: Option, - gauge_init: Option<(CurrencyIdOf, Perbill, BlockNumberFor)>, + gauge_init: Option<( + CurrencyIdOf, + BlockNumberFor, + Vec<(CurrencyIdOf, BalanceOf)>, + )>, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -581,8 +594,17 @@ pub mod pallet { if let Some(withdraw_limit_count) = withdraw_limit_count { pool_info.withdraw_limit_count = withdraw_limit_count; }; - if let Some((gauge_token, coefficient, max_block)) = gauge_init { - Self::create_gauge_pool(pid, &mut pool_info, gauge_token, coefficient, max_block)?; + if let Some((gauge_token, max_block, gauge_basic_rewards)) = gauge_init { + let gauge_basic_rewards_map: BTreeMap, BalanceOf> = + gauge_basic_rewards.into_iter().map(|(k, v)| (k, v)).collect(); + + Self::create_gauge_pool( + pid, + &mut pool_info, + gauge_token, + gauge_basic_rewards_map, + max_block, + )?; }; PoolInfos::::insert(pid, &pool_info); @@ -611,7 +633,7 @@ pub mod pallet { basic_rewards: Option, BalanceOf)>>, withdraw_limit_time: Option>, claim_limit_time: Option>, - gauge_coefficient: Option, + gauge_basic_rewards: Option, BalanceOf)>>, ) -> DispatchResult { T::ControlOrigin::ensure_origin(origin)?; @@ -628,12 +650,14 @@ pub mod pallet { if let Some(claim_limit_time) = claim_limit_time { pool_info.claim_limit_time = claim_limit_time; }; - if let Some(coefficient) = gauge_coefficient { + if let Some(gauge_basic_rewards) = gauge_basic_rewards { + let gauge_basic_rewards_map: BTreeMap, BalanceOf> = + gauge_basic_rewards.into_iter().map(|(k, v)| (k, v)).collect(); GaugePoolInfos::::mutate( pool_info.gauge.ok_or(Error::::GaugePoolNotExist)?, |gauge_pool_info_old| { if let Some(mut gauge_pool_info) = gauge_pool_info_old.take() { - gauge_pool_info.coefficient = coefficient; + gauge_pool_info.gauge_basic_rewards = gauge_basic_rewards_map; *gauge_pool_info_old = Some(gauge_pool_info); } }, diff --git a/pallets/farming/src/tests.rs b/pallets/farming/src/tests.rs index b42dcb892..ee36da66d 100644 --- a/pallets/farming/src/tests.rs +++ b/pallets/farming/src/tests.rs @@ -62,6 +62,8 @@ fn deposit() { let keeper: AccountId = ::Keeper::get().into_sub_account(pid); let reward_issuer: AccountId = ::RewardIssuer::get().into_sub_account(pid); + let mut gauge_basic_rewards = BTreeMap::, BalanceOf>::new(); + gauge_basic_rewards.entry(KSM).or_insert(1000); let gauge_pool_info2 = GaugePoolInfo { pid, token: KSM, @@ -71,7 +73,7 @@ fn deposit() { CurrencyIdOf, (BalanceOf, BalanceOf, BalanceOf), >::new(), - coefficient: Perbill::from_percent(100), + gauge_basic_rewards, max_block: 1000, gauge_amount: 200, total_time_factor: 39900, @@ -119,22 +121,32 @@ fn gauge() { ExtBuilder::default().one_hundred_for_alice_n_bob().build().execute_with(|| { let (pid, tokens) = init_gauge(); assert_eq!(Tokens::free_balance(KSM, &ALICE), 1900); + if let Some(gauge_pool_infos) = Farming::gauge_pool_infos(0) { + assert_eq!( + gauge_pool_infos.rewards, + BTreeMap::< + CurrencyIdOf, + (BalanceOf, BalanceOf, BalanceOf), + >::new() + ) + }; Farming::on_initialize(0); System::set_block_number(System::block_number() + 1); Farming::on_initialize(0); assert_ok!(Farming::claim(Origin::signed(ALICE), pid)); - assert_eq!(Tokens::free_balance(KSM, &ALICE), 2919); + assert_eq!(Tokens::free_balance(KSM, &ALICE), 2918); Farming::on_initialize(0); System::set_block_number(System::block_number() + 10); assert_ok!(Farming::deposit(Origin::signed(ALICE), pid, tokens, Some((100, 100)))); - assert_eq!(Tokens::free_balance(KSM, &ALICE), 1819); + assert_eq!(Tokens::free_balance(KSM, &ALICE), 1818); System::set_block_number(System::block_number() + 20); assert_ok!(Farming::claim(Origin::signed(ALICE), pid)); - assert_ok!(Farming::deposit(Origin::signed(BOB), pid, 10, None)); // 5482 -> 5471 + assert_eq!(Tokens::free_balance(KSM, &ALICE), 3163); + assert_ok!(Farming::deposit(Origin::signed(BOB), pid, 10, None)); assert_eq!(Tokens::free_balance(KSM, &BOB), 9699990); System::set_block_number(System::block_number() + 200); assert_ok!(Farming::claim(Origin::signed(ALICE), pid)); - assert_eq!(Tokens::free_balance(KSM, &ALICE), 5471); + assert_eq!(Tokens::free_balance(KSM, &ALICE), 5383); assert_eq!(Tokens::free_balance(KSM, &BOB), 9699990); assert_ok!(Farming::deposit(Origin::signed(BOB), pid, 0, Some((100, 100)))); System::set_block_number(System::block_number() + 200); @@ -169,12 +181,13 @@ fn init_gauge() -> (PoolId, BalanceOf) { let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; let tokens = 1000; let basic_rewards = vec![(KSM, 1000)]; + let gauge_basic_rewards = vec![(KSM, 900)]; assert_ok!(Farming::create_farming_pool( Origin::signed(ALICE), tokens_proportion.clone(), basic_rewards.clone(), - Some((KSM, Perbill::from_percent(90), 1000)), + Some((KSM, 1000, gauge_basic_rewards)), 0, 0, 0, @@ -195,12 +208,13 @@ fn init_no_gauge() -> (PoolId, BalanceOf) { let tokens_proportion = vec![(KSM, Perbill::from_percent(100))]; let tokens = 1000; let basic_rewards = vec![(KSM, 1000)]; + let gauge_basic_rewards = vec![(KSM, 1000)]; assert_ok!(Farming::create_farming_pool( Origin::signed(ALICE), tokens_proportion.clone(), basic_rewards.clone(), - Some((KSM, Perbill::from_percent(100), 1000)), + Some((KSM, 1000, gauge_basic_rewards)), 0, 0, 10,