From a62b8e3236037c3cc94ab90769ae55f9bba3849d Mon Sep 17 00:00:00 2001 From: Amiya Behera Date: Fri, 12 Jul 2024 15:36:25 +0530 Subject: [PATCH] incentives positive externality --- .../positive-externality/src/lib.rs | 176 +++++++++++------- docs/new_code.md | 1 + traits/trait-shared-storage/src/lib.rs | 1 - 3 files changed, 113 insertions(+), 65 deletions(-) diff --git a/custom-pallets/positive-externality/src/lib.rs b/custom-pallets/positive-externality/src/lib.rs index 5357bbf..d172e90 100644 --- a/custom-pallets/positive-externality/src/lib.rs +++ b/custom-pallets/positive-externality/src/lib.rs @@ -26,7 +26,9 @@ use frame_support::sp_runtime::traits::Saturating; use frame_support::sp_runtime::SaturatedConversion; use frame_support::{dispatch::DispatchResult, ensure}; use frame_support::{ - traits::{Currency, ExistenceRequirement, Get, OnUnbalanced, ReservableCurrency, WithdrawReasons}, + traits::{ + Currency, ExistenceRequirement, Get, OnUnbalanced, ReservableCurrency, WithdrawReasons, + }, PalletId, }; use frame_system::pallet_prelude::*; @@ -140,6 +142,11 @@ pub mod pallet { pub type ValidationBlock = StorageMap<_, Blake2_128Concat, T::AccountId, BlockNumberOf, ValueQuery>; + #[pallet::storage] + #[pallet::getter(fn got_incentives_positive_externality)] + pub type GotPositiveExternality = + StorageMap<_, Blake2_128Concat, SumTreeNameType, bool, ValueQuery>; + #[pallet::storage] #[pallet::getter(fn incentives_count)] pub type IncentiveCount = @@ -416,9 +423,51 @@ pub mod pallet { T::SchellingGameSharedSource::reveal_vote_score_helper_link(key, who, choice, salt)?; Ok(()) } - #[pallet::call_index(9)] #[pallet::weight(0)] + pub fn release_positive_externality_fund( + origin: OriginFor, + user_to_calculate: T::AccountId, + ) -> DispatchResult { + let who = ensure_signed(origin)?; + let block_number = >::get(user_to_calculate.clone()); + + let key = SumTreeName::PositiveExternality { + user_address: user_to_calculate.clone(), + block_number: block_number.clone(), + }; + + let score = T::SchellingGameSharedSource::get_mean_value_link(key.clone())?; + + // println!("Score {:?}", score); + + T::SharedStorageSource::set_positive_externality_link( + user_to_calculate.clone(), + score, + )?; + + let got_incentives_bool = >::get(key.clone()); + + if got_incentives_bool == false { + >::insert(key.clone(), true); + let balance = Self::u64_to_balance_saturated((score as u64) * 1000); + + let r = ::Currency::deposit_into_existing( + &user_to_calculate, + balance, + ) + .ok() + .unwrap(); + ::Reward::on_unbalanced(r); + } else { + Err(Error::::AlreadyFunded)? + } + + Ok(()) + } + + #[pallet::call_index(10)] + #[pallet::weight(0)] pub fn add_incentive_count( origin: OriginFor, user_to_calculate: T::AccountId, @@ -484,69 +533,68 @@ pub mod pallet { Ok(()) } + // Provide incentives - // Provide incentives - - #[pallet::call_index(10)] - #[pallet::weight(0)] - pub fn get_incentives(origin: OriginFor) -> DispatchResult { - let who = ensure_signed(origin)?; - let incentive_meta = >::get(); - let total_games_allowed = incentive_meta.total_number; - let incentive_count_option = >::get(&who); - match incentive_count_option { - Some(incentive) => { - let total_number_games = incentive.number_of_games; - if total_number_games >= total_games_allowed { - let new_incentives: Incentives = Incentives::new(0, 0, 0, 0); - >::mutate(&who, |incentive_option| { - *incentive_option = Some(new_incentives); - }); - - let total_win = incentive.winner; - let total_lost = incentive.loser; - - // Define multipliers - let win_multiplier = 10 * 100; - let lost_multiplier = incentive_meta.disincentive_times * 100; - - // Calculate total_win_incentives and total_lost_incentives - let total_win_incentives = total_win.checked_mul(win_multiplier); - let total_lost_incentives = total_lost.checked_mul(lost_multiplier); - - // Calculate total_incentives, handling overflow or negative errors - let total_incentives = match (total_win_incentives, total_lost_incentives) { - (Some(win), Some(lost)) => win.checked_sub(lost).unwrap_or(0), - _ => 0, // If multiplication overflowed, set total_incentives to 0 - }; - - let mut stake = incentive.total_stake; - // Deduct 1% of the stake if total_lost > total_win - if total_lost > total_win { - let stake_deduction = stake / 100; // 1% of the stake - stake = stake.checked_sub(stake_deduction).unwrap_or(stake); - // Safe subtraction - // println!("Stake deducted by 1%: {}", stake); - } - - let total_fund = stake.checked_add(total_incentives).unwrap_or(0); - - let balance = Self::u64_to_balance_saturated(total_fund); - - let r = - ::Currency::deposit_into_existing(&who, balance) - .ok() - .unwrap(); - ::Reward::on_unbalanced(r); - // Provide the incentives - } else { - Err(Error::::NotReachedMinimumDecision)? - } - } - None => Err(Error::::NoIncentiveCount)?, - } - Ok(()) - } + #[pallet::call_index(11)] + #[pallet::weight(0)] + pub fn get_incentives(origin: OriginFor) -> DispatchResult { + let who = ensure_signed(origin)?; + let incentive_meta = >::get(); + let total_games_allowed = incentive_meta.total_number; + let incentive_count_option = >::get(&who); + match incentive_count_option { + Some(incentive) => { + let total_number_games = incentive.number_of_games; + if total_number_games >= total_games_allowed { + let new_incentives: Incentives = Incentives::new(0, 0, 0, 0); + >::mutate(&who, |incentive_option| { + *incentive_option = Some(new_incentives); + }); + + let total_win = incentive.winner; + let total_lost = incentive.loser; + + // Define multipliers + let win_multiplier = 10 * 100; + let lost_multiplier = incentive_meta.disincentive_times * 100; + + // Calculate total_win_incentives and total_lost_incentives + let total_win_incentives = total_win.checked_mul(win_multiplier); + let total_lost_incentives = total_lost.checked_mul(lost_multiplier); + + // Calculate total_incentives, handling overflow or negative errors + let total_incentives = match (total_win_incentives, total_lost_incentives) { + (Some(win), Some(lost)) => win.checked_sub(lost).unwrap_or(0), + _ => 0, // If multiplication overflowed, set total_incentives to 0 + }; + + let mut stake = incentive.total_stake; + // Deduct 1% of the stake if total_lost > total_win + if total_lost > total_win { + let stake_deduction = stake / 100; // 1% of the stake + stake = stake.checked_sub(stake_deduction).unwrap_or(stake); + // Safe subtraction + // println!("Stake deducted by 1%: {}", stake); + } + + let total_fund = stake.checked_add(total_incentives).unwrap_or(0); + + let balance = Self::u64_to_balance_saturated(total_fund); + + let r = + ::Currency::deposit_into_existing(&who, balance) + .ok() + .unwrap(); + ::Reward::on_unbalanced(r); + // Provide the incentives + } else { + Err(Error::::NotReachedMinimumDecision)? + } + } + None => Err(Error::::NoIncentiveCount)?, + } + Ok(()) + } // #[pallet::call_index(9)] // #[pallet::weight(0)] diff --git a/docs/new_code.md b/docs/new_code.md index 344f710..cca1e02 100644 --- a/docs/new_code.md +++ b/docs/new_code.md @@ -183,6 +183,7 @@ impl pallet_positive_externality::Config for Runtime { type SharedStorageSource = SharedStorage; type Currency = Balances; type SchellingGameSharedSource = SchellingGameShared; + type Reward = (); } impl pallet_department_funding::Config for Runtime { diff --git a/traits/trait-shared-storage/src/lib.rs b/traits/trait-shared-storage/src/lib.rs index 0187712..e6665a7 100644 --- a/traits/trait-shared-storage/src/lib.rs +++ b/traits/trait-shared-storage/src/lib.rs @@ -2,7 +2,6 @@ use frame_support::pallet_prelude::DispatchResult; use sp_std::vec::Vec; - pub trait SharedStorageLink { type AccountId;