From a427baaba5144fde18e73f8020b5db6f95d7a4aa Mon Sep 17 00:00:00 2001 From: Juan Ignacio Rios Date: Mon, 27 May 2024 13:56:45 +0200 Subject: [PATCH] test-freeze-contribution-interaction --- pallets/funding/src/tests/3_auction.rs | 88 +++----- pallets/funding/src/tests/4_community.rs | 240 +++++++++++++++++++++- pallets/funding/src/tests/5_remainder.rs | 244 +++++++++++++++++++++++ 3 files changed, 513 insertions(+), 59 deletions(-) diff --git a/pallets/funding/src/tests/3_auction.rs b/pallets/funding/src/tests/3_auction.rs index 2a741d187..8e3ecceec 100644 --- a/pallets/funding/src/tests/3_auction.rs +++ b/pallets/funding/src/tests/3_auction.rs @@ -865,8 +865,7 @@ mod bid_extrinsic { #[cfg(test)] mod success { use super::*; - use frame_support::dispatch::DispatchResultWithPostInfo; - use frame_support::traits::fungible::InspectFreeze; + use frame_support::{dispatch::DispatchResultWithPostInfo, traits::fungible::InspectFreeze}; use pallet_balances::AccountData; #[test] @@ -1274,11 +1273,7 @@ mod bid_extrinsic { inst.execute(|| { assert_noop!( - Balances::transfer_allow_death( - RuntimeOrigin::signed(BIDDER_4), - ISSUER_1, - frozen_amount, - ), + Balances::transfer_allow_death(RuntimeOrigin::signed(BIDDER_4), ISSUER_1, frozen_amount,), TokenError::Frozen ); }); @@ -1306,11 +1301,10 @@ mod bid_extrinsic { assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::FundingFailed); let free_balance = inst.get_free_plmc_balance_for(BIDDER_4); - let bid_held_balance = inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Participation(project_id).into()); - let frozen_balance = inst.execute(|| { - mock::Balances::balance_frozen(&(), &BIDDER_4) - }); - let account_data = inst.execute(|| {System::account(&BIDDER_4)}).data; + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BIDDER_4)); + let account_data = inst.execute(|| System::account(&BIDDER_4)).data; assert_eq!(free_balance, inst.get_ed()); assert_eq!(bid_held_balance, frozen_amount); @@ -1324,20 +1318,14 @@ mod bid_extrinsic { assert_eq!(account_data, expected_account_data); inst.execute(|| { - PolimecFunding::settle_failed_bid( - RuntimeOrigin::signed(BIDDER_4), - project_id, - BIDDER_4, - 0 - ).unwrap(); + PolimecFunding::settle_failed_bid(RuntimeOrigin::signed(BIDDER_4), project_id, BIDDER_4, 0).unwrap(); }); let free_balance = inst.get_free_plmc_balance_for(BIDDER_4); - let bid_held_balance = inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Evaluation(project_id).into()); - let frozen_balance = inst.execute(|| { - mock::Balances::balance_frozen(&(), &BIDDER_4) - }); - let account_data = inst.execute(|| {System::account(&BIDDER_4)}).data; + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Evaluation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BIDDER_4)); + let account_data = inst.execute(|| System::account(&BIDDER_4)).data; assert_eq!(free_balance, inst.get_ed() + frozen_amount); assert_eq!(bid_held_balance, Zero::zero()); @@ -1384,11 +1372,7 @@ mod bid_extrinsic { inst.execute(|| { assert_noop!( - Balances::transfer_allow_death( - RuntimeOrigin::signed(BIDDER_4), - ISSUER_1, - frozen_amount, - ), + Balances::transfer_allow_death(RuntimeOrigin::signed(BIDDER_4), ISSUER_1, frozen_amount,), TokenError::Frozen ); }); @@ -1419,18 +1403,12 @@ mod bid_extrinsic { default_community_contributors(), default_multipliers(), ); - let plmc_required = inst.calculate_contributed_plmc_spent( - contributions.clone(), - wap - ); + let plmc_required = inst.calculate_contributed_plmc_spent(contributions.clone(), wap); let plmc_existential_deposits = plmc_required.accounts().existential_deposits(); inst.mint_plmc_to(plmc_required.clone()); inst.mint_plmc_to(plmc_existential_deposits.clone()); - let usdt_required = inst.calculate_contributed_funding_asset_spent( - contributions.clone(), - wap - ); + let usdt_required = inst.calculate_contributed_funding_asset_spent(contributions.clone(), wap); inst.mint_foreign_asset_to(usdt_required.clone()); inst.contribute_for_users(project_id, contributions).unwrap(); @@ -1443,11 +1421,10 @@ mod bid_extrinsic { inst.jump_to_block(settlement_block); let free_balance = inst.get_free_plmc_balance_for(BIDDER_4); - let bid_held_balance = inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Participation(project_id).into()); - let frozen_balance = inst.execute(|| { - mock::Balances::balance_frozen(&(), &BIDDER_4) - }); - let account_data = inst.execute(|| {System::account(&BIDDER_4)}).data; + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BIDDER_4)); + let account_data = inst.execute(|| System::account(&BIDDER_4)).data; assert_eq!(free_balance, inst.get_ed()); assert_eq!(bid_held_balance, frozen_amount); @@ -1461,20 +1438,15 @@ mod bid_extrinsic { assert_eq!(account_data, expected_account_data); inst.execute(|| { - PolimecFunding::settle_successful_bid( - RuntimeOrigin::signed(BIDDER_4), - project_id, - BIDDER_4, - 0 - ).unwrap(); + PolimecFunding::settle_successful_bid(RuntimeOrigin::signed(BIDDER_4), project_id, BIDDER_4, 0) + .unwrap(); }); let free_balance = inst.get_free_plmc_balance_for(BIDDER_4); - let bid_held_balance = inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Participation(project_id).into()); - let frozen_balance = inst.execute(|| { - mock::Balances::balance_frozen(&(), &BIDDER_4) - }); - let account_data = inst.execute(|| {System::account(&BIDDER_4)}).data; + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BIDDER_4)); + let account_data = inst.execute(|| System::account(&BIDDER_4)).data; assert_eq!(free_balance, inst.get_ed()); assert_eq!(bid_held_balance, frozen_amount); @@ -1487,7 +1459,8 @@ mod bid_extrinsic { }; assert_eq!(account_data, expected_account_data); - let vest_duration = MultiplierOf::::new(5u8).unwrap().calculate_vesting_duration::(); + let vest_duration = + MultiplierOf::::new(5u8).unwrap().calculate_vesting_duration::(); let now = inst.current_block(); inst.jump_to_block(now + vest_duration + 1u64); inst.execute(|| { @@ -1498,11 +1471,10 @@ mod bid_extrinsic { }); let free_balance = inst.get_free_plmc_balance_for(BIDDER_4); - let bid_held_balance = inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Participation(project_id).into()); - let frozen_balance = inst.execute(|| { - mock::Balances::balance_frozen(&(), &BIDDER_4) - }); - let account_data = inst.execute(|| {System::account(&BIDDER_4)}).data; + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BIDDER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BIDDER_4)); + let account_data = inst.execute(|| System::account(&BIDDER_4)).data; assert_eq!(free_balance, inst.get_ed() + frozen_amount); assert_eq!(bid_held_balance, Zero::zero()); diff --git a/pallets/funding/src/tests/4_community.rs b/pallets/funding/src/tests/4_community.rs index e041482b7..c3741171c 100644 --- a/pallets/funding/src/tests/4_community.rs +++ b/pallets/funding/src/tests/4_community.rs @@ -315,7 +315,9 @@ mod community_contribute_extrinsic { #[cfg(test)] mod success { use super::*; - use frame_support::dispatch::DispatchResultWithPostInfo; + use frame_support::{dispatch::DispatchResultWithPostInfo, traits::fungible::InspectFreeze}; + use pallet_balances::AccountData; + use polimec_common_test_utils::get_mock_jwt; #[test] fn evaluation_bond_counts_towards_contribution() { @@ -842,6 +844,242 @@ mod community_contribute_extrinsic { bid_should_succeed(BIDDER_6, InvestorType::Retail, BIDDER_6); bid_should_succeed(BUYER_6, InvestorType::Retail, BIDDER_6); } + + #[test] + fn can_contribute_with_frozen_tokens_funding_failed() { + 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_community_contributing_project( + project_metadata.clone(), + issuer, + default_evaluations(), + vec![], + ); + let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); + + let contribution = ContributionParams::new(BUYER_4, 500 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT); + let plmc_required = inst.calculate_contributed_plmc_spent(vec![contribution.clone()], wap); + 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(&(), &BUYER_4, plmc_required[0].plmc_amount).unwrap(); + }); + + let usdt_required = inst.calculate_contributed_funding_asset_spent(vec![contribution.clone()], wap); + inst.mint_foreign_asset_to(usdt_required); + + inst.execute(|| { + assert_noop!( + Balances::transfer_allow_death(RuntimeOrigin::signed(BUYER_4), ISSUER_1, frozen_amount,), + TokenError::Frozen + ); + }); + + inst.execute(|| { + assert_ok!(PolimecFunding::community_contribute( + RuntimeOrigin::signed(BUYER_4), + get_mock_jwt_with_cid( + BUYER_4, + InvestorType::Institutional, + generate_did_from_account(BUYER_4), + project_metadata.clone().policy_ipfs_cid.unwrap() + ), + project_id, + contribution.amount, + contribution.multiplier, + contribution.asset + )); + }); + + 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(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed()); + assert_eq!(bid_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); + + inst.execute(|| { + PolimecFunding::settle_failed_contribution(RuntimeOrigin::signed(BUYER_4), project_id, BUYER_4, 0) + .unwrap(); + }); + + let free_balance = inst.get_free_plmc_balance_for(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Evaluation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed() + frozen_amount); + assert_eq!(bid_held_balance, Zero::zero()); + assert_eq!(frozen_balance, frozen_amount); + let expected_account_data = AccountData { + free: inst.get_ed() + frozen_amount, + reserved: Zero::zero(), + frozen: frozen_amount, + flags: Default::default(), + }; + assert_eq!(account_data, expected_account_data); + assert_eq!(account_data.frozen, account_data.free - inst.get_ed()); + } + + #[test] + fn can_contribute_with_frozen_tokens_funding_success() { + 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_community_contributing_project( + project_metadata.clone(), + issuer, + default_evaluations(), + default_bids(), + ); + let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); + + let contribution = ContributionParams::new(BUYER_4, 500 * CT_UNIT, 5u8, AcceptedFundingAsset::USDT); + let plmc_required = inst.calculate_contributed_plmc_spent(vec![contribution.clone()], wap); + 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(&(), &BUYER_4, plmc_required[0].plmc_amount).unwrap(); + }); + + let usdt_required = inst.calculate_contributed_funding_asset_spent(vec![contribution.clone()], wap); + inst.mint_foreign_asset_to(usdt_required); + + inst.execute(|| { + assert_noop!( + Balances::transfer_allow_death(RuntimeOrigin::signed(BUYER_4), ISSUER_1, frozen_amount,), + TokenError::Frozen + ); + }); + + inst.execute(|| { + assert_ok!(PolimecFunding::community_contribute( + RuntimeOrigin::signed(BUYER_4), + get_mock_jwt_with_cid( + BUYER_4, + InvestorType::Institutional, + generate_did_from_account(BUYER_4), + project_metadata.clone().policy_ipfs_cid.unwrap() + ), + project_id, + contribution.amount, + contribution.multiplier, + contribution.asset + )); + }); + + 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::AwaitingProjectDecision); + inst.execute(|| { + assert_ok!(PolimecFunding::decide_project_outcome( + RuntimeOrigin::signed(ISSUER_1), + get_mock_jwt(ISSUER_1, InvestorType::Institutional, generate_did_from_account(ISSUER_1)), + project_id, + FundingOutcomeDecision::AcceptFunding + )); + }); + let decision_block = inst + .get_update_block(project_id, &UpdateType::ProjectDecision(FundingOutcomeDecision::AcceptFunding)) + .unwrap(); + inst.jump_to_block(decision_block); + + let settlement_block = inst.get_update_block(project_id, &UpdateType::StartSettlement).unwrap(); + inst.jump_to_block(settlement_block); + + let free_balance = inst.get_free_plmc_balance_for(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed()); + assert_eq!(bid_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); + + inst.execute(|| { + PolimecFunding::settle_successful_contribution(RuntimeOrigin::signed(BUYER_4), project_id, BUYER_4, 0) + .unwrap(); + }); + + let free_balance = inst.get_free_plmc_balance_for(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed()); + assert_eq!(bid_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 vest_duration = + MultiplierOf::::new(5u8).unwrap().calculate_vesting_duration::(); + let now = inst.current_block(); + inst.jump_to_block(now + vest_duration + 1u64); + inst.execute(|| { + assert_ok!(mock::LinearRelease::vest( + RuntimeOrigin::signed(BUYER_4), + HoldReason::Participation(project_id).into() + )); + }); + + let free_balance = inst.get_free_plmc_balance_for(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed() + frozen_amount); + assert_eq!(bid_held_balance, Zero::zero()); + assert_eq!(frozen_balance, frozen_amount); + let expected_account_data = AccountData { + free: inst.get_ed() + frozen_amount, + reserved: Zero::zero(), + frozen: frozen_amount, + flags: Default::default(), + }; + assert_eq!(account_data, expected_account_data); + } } #[cfg(test)] diff --git a/pallets/funding/src/tests/5_remainder.rs b/pallets/funding/src/tests/5_remainder.rs index b87e59967..f3a0db36b 100644 --- a/pallets/funding/src/tests/5_remainder.rs +++ b/pallets/funding/src/tests/5_remainder.rs @@ -289,6 +289,9 @@ mod remaining_contribute_extrinsic { #[cfg(test)] mod success { use super::*; + use frame_support::traits::fungible::InspectFreeze; + use pallet_balances::AccountData; + use polimec_common_test_utils::get_mock_jwt; #[test] fn remainder_contributor_was_evaluator() { @@ -806,6 +809,247 @@ mod remaining_contribute_extrinsic { } } } + + #[test] + fn can_contribute_with_frozen_tokens_funding_failed() { + 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_remainder_contributing_project( + project_metadata.clone(), + issuer, + default_evaluations(), + vec![], + vec![], + ); + let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); + + let contribution = ContributionParams::new(BUYER_4, 500 * CT_UNIT, 1u8, AcceptedFundingAsset::USDT); + let plmc_required = inst.calculate_contributed_plmc_spent(vec![contribution.clone()], wap); + 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(&(), &BUYER_4, plmc_required[0].plmc_amount).unwrap(); + }); + + let usdt_required = inst.calculate_contributed_funding_asset_spent(vec![contribution.clone()], wap); + inst.mint_foreign_asset_to(usdt_required); + + inst.execute(|| { + assert_noop!( + Balances::transfer_allow_death(RuntimeOrigin::signed(BUYER_4), ISSUER_1, frozen_amount,), + TokenError::Frozen + ); + }); + + inst.execute(|| { + assert_ok!(PolimecFunding::remaining_contribute( + RuntimeOrigin::signed(BUYER_4), + get_mock_jwt_with_cid( + BUYER_4, + InvestorType::Institutional, + generate_did_from_account(BUYER_4), + project_metadata.clone().policy_ipfs_cid.unwrap() + ), + project_id, + contribution.amount, + contribution.multiplier, + contribution.asset + )); + }); + + 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(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed()); + assert_eq!(bid_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); + + inst.execute(|| { + PolimecFunding::settle_failed_contribution(RuntimeOrigin::signed(BUYER_4), project_id, BUYER_4, 0) + .unwrap(); + }); + + let free_balance = inst.get_free_plmc_balance_for(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Evaluation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed() + frozen_amount); + assert_eq!(bid_held_balance, Zero::zero()); + assert_eq!(frozen_balance, frozen_amount); + let expected_account_data = AccountData { + free: inst.get_ed() + frozen_amount, + reserved: Zero::zero(), + frozen: frozen_amount, + flags: Default::default(), + }; + assert_eq!(account_data, expected_account_data); + assert_eq!(account_data.frozen, account_data.free - inst.get_ed()); + } + + #[test] + fn can_contribute_with_frozen_tokens_funding_success() { + 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_remainder_contributing_project( + project_metadata.clone(), + issuer, + default_evaluations(), + default_bids(), + vec![], + ); + let wap = inst.get_project_details(project_id).weighted_average_price.unwrap(); + + let contribution = ContributionParams::new(BUYER_4, 500 * CT_UNIT, 5u8, AcceptedFundingAsset::USDT); + let plmc_required = inst.calculate_contributed_plmc_spent(vec![contribution.clone()], wap); + 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(&(), &BUYER_4, plmc_required[0].plmc_amount).unwrap(); + }); + + let usdt_required = inst.calculate_contributed_funding_asset_spent(vec![contribution.clone()], wap); + inst.mint_foreign_asset_to(usdt_required); + + inst.execute(|| { + assert_noop!( + Balances::transfer_allow_death(RuntimeOrigin::signed(BUYER_4), ISSUER_1, frozen_amount,), + TokenError::Frozen + ); + }); + + inst.execute(|| { + assert_ok!(PolimecFunding::remaining_contribute( + RuntimeOrigin::signed(BUYER_4), + get_mock_jwt_with_cid( + BUYER_4, + InvestorType::Institutional, + generate_did_from_account(BUYER_4), + project_metadata.clone().policy_ipfs_cid.unwrap() + ), + project_id, + contribution.amount, + contribution.multiplier, + contribution.asset + )); + }); + + inst.finish_funding(project_id).unwrap(); + + assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::AwaitingProjectDecision); + inst.execute(|| { + assert_ok!(PolimecFunding::decide_project_outcome( + RuntimeOrigin::signed(ISSUER_1), + get_mock_jwt_with_cid( + ISSUER_1, + InvestorType::Institutional, + generate_did_from_account(ISSUER_1), + project_metadata.policy_ipfs_cid.unwrap() + ), + project_id, + FundingOutcomeDecision::AcceptFunding + )); + }); + let decision_block = inst + .get_update_block(project_id, &UpdateType::ProjectDecision(FundingOutcomeDecision::AcceptFunding)) + .unwrap(); + inst.jump_to_block(decision_block); + + let settlement_block = inst.get_update_block(project_id, &UpdateType::StartSettlement).unwrap(); + inst.jump_to_block(settlement_block); + + let free_balance = inst.get_free_plmc_balance_for(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed()); + assert_eq!(bid_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); + + inst.execute(|| { + PolimecFunding::settle_successful_contribution(RuntimeOrigin::signed(BUYER_4), project_id, BUYER_4, 0) + .unwrap(); + }); + + let free_balance = inst.get_free_plmc_balance_for(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed()); + assert_eq!(bid_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 vest_duration = + MultiplierOf::::new(5u8).unwrap().calculate_vesting_duration::(); + let now = inst.current_block(); + inst.jump_to_block(now + vest_duration + 1u64); + inst.execute(|| { + assert_ok!(mock::LinearRelease::vest( + RuntimeOrigin::signed(BUYER_4), + HoldReason::Participation(project_id).into() + )); + }); + + let free_balance = inst.get_free_plmc_balance_for(BUYER_4); + let bid_held_balance = + inst.get_reserved_plmc_balance_for(BUYER_4, HoldReason::Participation(project_id).into()); + let frozen_balance = inst.execute(|| mock::Balances::balance_frozen(&(), &BUYER_4)); + let account_data = inst.execute(|| System::account(&BUYER_4)).data; + + assert_eq!(free_balance, inst.get_ed() + frozen_amount); + assert_eq!(bid_held_balance, Zero::zero()); + assert_eq!(frozen_balance, frozen_amount); + let expected_account_data = AccountData { + free: inst.get_ed() + frozen_amount, + reserved: Zero::zero(), + frozen: frozen_amount, + flags: Default::default(), + }; + assert_eq!(account_data, expected_account_data); + } } #[cfg(test)]