Skip to content

Commit

Permalink
test-freeze-interactions
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed May 27, 2024
1 parent 7574c2c commit f8b042c
Show file tree
Hide file tree
Showing 2 changed files with 174 additions and 85 deletions.
116 changes: 116 additions & 0 deletions pallets/funding/src/tests/2_evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,12 @@ mod evaluate_extrinsic {
#[cfg(test)]
mod success {
use super::*;
use frame_support::traits::{
fungible::{InspectFreeze, Mutate},
tokens::Preservation,
};
use pallet_balances::AccountData;
use sp_runtime::DispatchError::Token;

#[test]
fn all_investor_types() {
Expand Down Expand Up @@ -618,6 +624,116 @@ mod evaluate_extrinsic {
assert_eq!(stored_evaluation, &expected_evaluation_item);
});
}

#[test]
fn can_evaluate_with_frozen_tokens() {
let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext())));
let issuer = ISSUER_1;
let project_metadata = default_project_metadata(issuer);
let project_id = inst.create_evaluating_project(project_metadata.clone(), issuer);

let evaluation = UserToUSDBalance::new(EVALUATOR_4, 500 * USD_UNIT);
let plmc_required = inst.calculate_evaluation_plmc_spent(vec![evaluation.clone()]);
let frozen_amount = plmc_required[0].plmc_amount;
let plmc_existential_deposits = plmc_required.accounts().existential_deposits();

inst.mint_plmc_to(plmc_existential_deposits);
inst.mint_plmc_to(plmc_required.clone());

inst.execute(|| {
mock::Balances::set_freeze(&(), &EVALUATOR_4, plmc_required[0].plmc_amount).unwrap();
});

inst.execute(|| {
assert_noop!(
Balances::transfer_allow_death(RuntimeOrigin::signed(EVALUATOR_4), ISSUER_1, frozen_amount,),
TokenError::Frozen
);
});

inst.execute(|| {
assert_ok!(PolimecFunding::evaluate(
RuntimeOrigin::signed(EVALUATOR_4),
get_mock_jwt_with_cid(
EVALUATOR_4,
InvestorType::Retail,
generate_did_from_account(EVALUATOR_4),
project_metadata.clone().policy_ipfs_cid.unwrap()
),
project_id,
evaluation.usd_amount
));
});

let new_evaluations = default_evaluations();
let new_plmc_required = inst.calculate_evaluation_plmc_spent(new_evaluations.clone());
let new_plmc_existential_deposits = new_plmc_required.accounts().existential_deposits();
inst.mint_plmc_to(new_plmc_existential_deposits);
inst.mint_plmc_to(new_plmc_required.clone());
inst.evaluate_for_users(project_id, new_evaluations).unwrap();

inst.start_auction(project_id, ISSUER_1).unwrap();
inst.start_community_funding(project_id).unwrap();
inst.start_remainder_or_end_funding(project_id).unwrap();
inst.finish_funding(project_id).unwrap();

assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingFailed);

let free_balance = inst.get_free_plmc_balance_for(EVALUATOR_4);
let evaluation_held_balance =
inst.get_reserved_plmc_balance_for(EVALUATOR_4, HoldReason::Evaluation(project_id).into());
let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &EVALUATOR_4));
let account_data = inst.execute(|| System::account(&EVALUATOR_4)).data;

assert_eq!(free_balance, inst.get_ed());
assert_eq!(evaluation_held_balance, frozen_amount);
assert_eq!(frozen_balance, frozen_amount);
let expected_account_data = AccountData {
free: inst.get_ed(),
reserved: frozen_amount,
frozen: frozen_amount,
flags: Default::default(),
};
assert_eq!(account_data, expected_account_data);

let treasury_account = <TestRuntime as Config>::ProtocolGrowthTreasury::get();
let pre_slash_treasury_balance = inst.get_free_plmc_balance_for(treasury_account);
inst.execute(|| {
PolimecFunding::settle_failed_evaluation(
RuntimeOrigin::signed(EVALUATOR_4),
project_id,
EVALUATOR_4,
0,
)
.unwrap();
});

let post_slash_treasury_balance = inst.get_free_plmc_balance_for(treasury_account);
let free_balance = inst.get_free_plmc_balance_for(EVALUATOR_4);
let evaluation_held_balance =
inst.get_reserved_plmc_balance_for(EVALUATOR_4, HoldReason::Evaluation(project_id).into());
let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &EVALUATOR_4));
let account_data = inst.execute(|| System::account(&EVALUATOR_4)).data;

let post_slash_evaluation_plmc =
frozen_amount - (<TestRuntime as Config>::EvaluatorSlash::get() * frozen_amount);
assert_eq!(free_balance, inst.get_ed() + post_slash_evaluation_plmc);
assert_eq!(evaluation_held_balance, Zero::zero());
assert_eq!(frozen_balance, frozen_amount);
let expected_account_data = AccountData {
free: inst.get_ed() + post_slash_evaluation_plmc,
reserved: Zero::zero(),
frozen: frozen_amount,
flags: Default::default(),
};
assert_eq!(account_data, expected_account_data);

assert!(account_data.frozen > account_data.free);
assert_eq!(
post_slash_treasury_balance,
pre_slash_treasury_balance + <TestRuntime as Config>::EvaluatorSlash::get() * frozen_amount
);
}
}

#[cfg(test)]
Expand Down
143 changes: 58 additions & 85 deletions pallets/funding/src/tests/7_settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,64 @@ mod settle_failed_evaluation_extrinsic {
#[cfg(test)]
mod success {
use super::*;

#[test]
fn evaluation_unchanged() {
let percentage = 89u64;

let (mut inst, project_id) =
create_project_with_funding_percentage(percentage, Some(FundingOutcomeDecision::RejectFunding));

let first_evaluation = inst.get_evaluations(project_id).into_iter().next().unwrap();
let evaluator = first_evaluation.evaluator;
let prev_balance = inst.get_free_plmc_balance_for(evaluator);

assert_eq!(
inst.get_project_details(project_id).evaluation_round_info.evaluators_outcome,
EvaluatorsOutcomeOf::<TestRuntime>::Unchanged
);

assert_ok!(inst.execute(|| PolimecFunding::settle_failed_evaluation(
RuntimeOrigin::signed(evaluator),
project_id,
evaluator,
first_evaluation.id
)));

let post_balance = inst.get_free_plmc_balance_for(evaluator);
assert_eq!(post_balance, prev_balance + first_evaluation.current_plmc_bond);
}

#[test]
fn evaluation_slashed() {
let percentage = 50u64;
let (mut inst, project_id) =
create_project_with_funding_percentage(percentage, Some(FundingOutcomeDecision::RejectFunding));

let first_evaluation = inst.get_evaluations(project_id).into_iter().next().unwrap();
let evaluator = first_evaluation.evaluator;
let prev_balance = inst.get_free_plmc_balances_for(vec![evaluator])[0].plmc_amount;

assert_eq!(
inst.get_project_details(project_id).evaluation_round_info.evaluators_outcome,
EvaluatorsOutcomeOf::<TestRuntime>::Slashed
);

assert_ok!(inst.execute(|| PolimecFunding::settle_failed_evaluation(
RuntimeOrigin::signed(evaluator),
project_id,
evaluator,
first_evaluation.id
)));

let post_balance = inst.get_free_plmc_balances_for(vec![evaluator])[0].plmc_amount;
assert_eq!(
post_balance,
prev_balance +
(Percent::from_percent(100) - <TestRuntime as Config>::EvaluatorSlash::get()) *
first_evaluation.current_plmc_bond
);
}
}

#[cfg(test)]
Expand Down Expand Up @@ -434,91 +492,6 @@ mod settle_failed_contribution_extrinsic {
}
}

/// Test that the correct amount of PLMC is slashed from the evaluator independent of the
/// project outcome.
#[test]
fn evaluator_slashed_if_between_33_and_75() {
let percentage = 50u64;
let project_1 = create_project_with_funding_percentage(percentage, Some(FundingOutcomeDecision::AcceptFunding));
let project_2 = create_project_with_funding_percentage(percentage, Some(FundingOutcomeDecision::RejectFunding));
let projects = vec![project_1, project_2];

for (mut inst, project_id) in projects {
let first_evaluation = inst.get_evaluations(project_id).into_iter().next().unwrap();
let evaluator = first_evaluation.evaluator;

inst.execute(|| {
let prev_balance = <TestRuntime as Config>::NativeCurrency::balance(&evaluator);
match ProjectsDetails::<TestRuntime>::get(project_id).unwrap().status {
ProjectStatus::FundingSuccessful => {
assert_ok!(crate::Pallet::<TestRuntime>::settle_successful_evaluation(
RuntimeOrigin::signed(evaluator),
project_id,
evaluator,
first_evaluation.id
));
},
ProjectStatus::FundingFailed => {
assert_ok!(crate::Pallet::<TestRuntime>::settle_failed_evaluation(
RuntimeOrigin::signed(evaluator),
project_id,
evaluator,
first_evaluation.id
));
},
_ => panic!("unexpected project status"),
}
let balance = <TestRuntime as Config>::NativeCurrency::balance(&evaluator);
assert_eq!(
balance,
prev_balance +
(Percent::from_percent(100) - <TestRuntime as Config>::EvaluatorSlash::get()) *
first_evaluation.current_plmc_bond
);
});
}
}

// Test that the evaluators PLMC bond is not slashed if the project is between 76 and 89
// percent funded independent of the project outcome.
#[test]
fn evaluator_plmc_unchanged_between_76_and_89() {
let percentage = 80u64;
let project_1 = create_project_with_funding_percentage(percentage, Some(FundingOutcomeDecision::AcceptFunding));
let project_2 = create_project_with_funding_percentage(percentage, Some(FundingOutcomeDecision::RejectFunding));
let projects = vec![project_1, project_2];

for (mut inst, project_id) in projects {
let first_evaluation = inst.get_evaluations(project_id).into_iter().next().unwrap();
let evaluator = first_evaluation.evaluator;

inst.execute(|| {
let prev_balance = <TestRuntime as Config>::NativeCurrency::balance(&evaluator);
match ProjectsDetails::<TestRuntime>::get(project_id).unwrap().status {
ProjectStatus::FundingSuccessful => {
assert_ok!(crate::Pallet::<TestRuntime>::settle_successful_evaluation(
RuntimeOrigin::signed(evaluator),
project_id,
evaluator,
first_evaluation.id
));
},
ProjectStatus::FundingFailed => {
assert_ok!(crate::Pallet::<TestRuntime>::settle_failed_evaluation(
RuntimeOrigin::signed(evaluator),
project_id,
evaluator,
first_evaluation.id
));
},
_ => panic!("unexpected project status"),
}
let balance = <TestRuntime as Config>::NativeCurrency::balance(&evaluator);
assert_eq!(balance, prev_balance + first_evaluation.current_plmc_bond);
});
}
}

#[test]
fn bid_is_correctly_settled_for_successful_project() {
let percentage = 100u64;
Expand Down

0 comments on commit f8b042c

Please sign in to comment.