diff --git a/pallets/funding/src/functions/2_evaluation.rs b/pallets/funding/src/functions/2_evaluation.rs index b97e071a2..e33cc7c57 100644 --- a/pallets/funding/src/functions/2_evaluation.rs +++ b/pallets/funding/src/functions/2_evaluation.rs @@ -94,6 +94,7 @@ impl Pallet { ensure!(usd_amount >= T::MinUsdPerEvaluation::get(), Error::::TooLow); ensure!(project_details.issuer_did != did, Error::::ParticipationToOwnProject); ensure!(project_details.status == ProjectStatus::EvaluationRound, Error::::IncorrectRound); + ensure!(project_details.round_duration.started(now) && !project_details.round_duration.ended(now), Error::::IncorrectRound); ensure!(total_evaluations_count < T::MaxEvaluationsPerProject::get(), Error::::TooManyProjectParticipations); ensure!(user_evaluations_count < T::MaxEvaluationsPerUser::get(), Error::::TooManyUserParticipations); diff --git a/pallets/funding/src/functions/3_auction.rs b/pallets/funding/src/functions/3_auction.rs index 2c6c94852..91de9e0de 100644 --- a/pallets/funding/src/functions/3_auction.rs +++ b/pallets/funding/src/functions/3_auction.rs @@ -89,6 +89,7 @@ impl Pallet { ensure!(ct_amount > Zero::zero(), Error::::TooLow); ensure!(did != project_details.issuer_did, Error::::ParticipationToOwnProject); ensure!(matches!(project_details.status, ProjectStatus::AuctionRound), Error::::IncorrectRound); + ensure!(project_details.round_duration.started(now) && !project_details.round_duration.ended(now), Error::::IncorrectRound); ensure!( project_metadata.participation_currencies.contains(&funding_asset), Error::::FundingAssetNotAccepted diff --git a/pallets/funding/src/functions/4_contribution.rs b/pallets/funding/src/functions/4_contribution.rs index 5f334d45d..9896e8342 100644 --- a/pallets/funding/src/functions/4_contribution.rs +++ b/pallets/funding/src/functions/4_contribution.rs @@ -24,9 +24,8 @@ impl Pallet { let now = >::block_number(); let remainder_started = now >= remainder_start; - let round_end = project_details.round_duration.end().ok_or(Error::::ImpossibleState)?; ensure!(!did_has_winning_bid || remainder_started, Error::::UserHasWinningBid); - ensure!(now < round_end, Error::::TooLateForRound); + ensure!(project_details.round_duration.started(now) && !project_details.round_duration.ended(now), Error::::IncorrectRound); let buyable_tokens = token_amount.min(project_details.remaining_contribution_tokens); if buyable_tokens.is_zero() { diff --git a/pallets/funding/src/tests/2_evaluation.rs b/pallets/funding/src/tests/2_evaluation.rs index c5e0d6800..8895e4650 100644 --- a/pallets/funding/src/tests/2_evaluation.rs +++ b/pallets/funding/src/tests/2_evaluation.rs @@ -982,5 +982,33 @@ mod evaluate_extrinsic { ); }); } + + #[test] + fn evaluated_after_end_block_before_transitioning_project() { + 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, None); + let project_details = inst.get_project_details(project_id); + let end_block = project_details.round_duration.end().unwrap(); + inst.jump_to_block(end_block + 1); + assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::EvaluationRound); + inst.execute(|| { + assert_noop!( + PolimecFunding::evaluate( + RuntimeOrigin::signed(EVALUATOR_1), + get_mock_jwt_with_cid( + EVALUATOR_1, + InvestorType::Retail, + generate_did_from_account(EVALUATOR_1), + project_metadata.clone().policy_ipfs_cid.unwrap() + ), + project_id, + 500 * USD_UNIT, + ), + Error::::IncorrectRound + ); + }); + } } } diff --git a/pallets/funding/src/tests/3_auction.rs b/pallets/funding/src/tests/3_auction.rs index 154fa3d9d..62e4707b4 100644 --- a/pallets/funding/src/tests/3_auction.rs +++ b/pallets/funding/src/tests/3_auction.rs @@ -1863,6 +1863,35 @@ mod bid_extrinsic { ); }); } + + #[test] + fn bid_after_end_block_before_transitioning_project() { + let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); + let project_metadata = default_project_metadata(ISSUER_1); + let project_id = + inst.create_auctioning_project(project_metadata.clone(), ISSUER_1, None, default_evaluations()); + let end_block = inst.get_project_details(project_id).round_duration.end.unwrap(); + inst.jump_to_block(end_block + 1); + assert_eq!(inst.get_project_details(project_id).status, ProjectStatus::AuctionRound); + inst.execute(|| { + assert_noop!( + PolimecFunding::bid( + RuntimeOrigin::signed(BIDDER_1), + get_mock_jwt_with_cid( + BIDDER_1, + InvestorType::Professional, + generate_did_from_account(BIDDER_1), + project_metadata.clone().policy_ipfs_cid.unwrap() + ), + project_id, + 5000 * CT_UNIT, + ParticipationMode::Classic(1u8), + AcceptedFundingAsset::USDT + ), + Error::::IncorrectRound + ); + }); + } } } diff --git a/pallets/funding/src/tests/4_contribution.rs b/pallets/funding/src/tests/4_contribution.rs index 587c240d6..4ea8c9688 100644 --- a/pallets/funding/src/tests/4_contribution.rs +++ b/pallets/funding/src/tests/4_contribution.rs @@ -2184,5 +2184,35 @@ mod contribute_extrinsic { ); }); } + + #[test] + fn contributed_after_end_block_before_transitioning_project() { + let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext()))); + let project_metadata = default_project_metadata(ISSUER_1); + let project_id = + inst.create_community_contributing_project(project_metadata.clone(), ISSUER_1, None, default_evaluations(), vec![]); + let end_block = inst.get_project_details(project_id).round_duration.end.unwrap(); + inst.jump_to_block(end_block + 1); + assert!(matches!(inst.get_project_details(project_id).status, ProjectStatus::CommunityRound(..))); + + inst.execute(|| { + assert_noop!( + PolimecFunding::contribute( + RuntimeOrigin::signed(BUYER_1), + get_mock_jwt_with_cid( + BUYER_1, + InvestorType::Professional, + generate_did_from_account(BUYER_1), + project_metadata.clone().policy_ipfs_cid.unwrap() + ), + project_id, + 5000 * CT_UNIT, + ParticipationMode::Classic(1u8), + AcceptedFundingAsset::USDT + ), + Error::::IncorrectRound + ); + }); + } } }