Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix for campaign settlement #67

Merged
merged 3 commits into from
Jul 25, 2022
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions flow/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,9 @@ pub mod pallet {
fn on_initialize(block_number: T::BlockNumber) -> Weight {
let mut contributors: u32 = 0;
Self::process_campaigns(&block_number, FlowState::Finalizing, &mut contributors);
Self::process_campaigns(&block_number, FlowState::Reverting, &mut contributors);
if contributors < T::MaxContributorsProcessing::get() {
Self::process_campaigns(&block_number, FlowState::Reverting, &mut contributors);
}
T::WeightInfo::on_initialize(contributors)
}

Expand Down Expand Up @@ -944,13 +946,13 @@ impl<T: Config> Pallet<T> {
}

fn finalize_campaign(
block_number: &T::BlockNumber, processed: &mut u32,
block_number: &T::BlockNumber, total_processed: &mut u32,
campaign: &Campaign<T::Hash, T::AccountId, T::Balance, T::BlockNumber, Moment, BoundedVec<u8, T::StringLimit>>,
campaign_balance: &T::Balance, org_treasury: &T::AccountId,
contributors: &Vec<T::AccountId>, owner: &T::AccountId
) {
let processed_offset = ContributorsFinalized::<T>::get(campaign.id);
let offset: usize = usize::try_from(processed_offset).unwrap();
let mut processed = ContributorsFinalized::<T>::get(campaign.id);
let offset: usize = usize::try_from(processed).unwrap();
for contributor in &contributors[offset..] {
if contributor == owner {
continue;
Expand All @@ -973,13 +975,14 @@ impl<T: Config> Pallet<T> {
},
Ok(_) => { }
}
*processed += 1;
if *processed >= T::MaxContributorsProcessing::get() {
ContributorsFinalized::<T>::insert(campaign.id, processed_offset + *processed);
*total_processed += 1;
processed += 1;
if *total_processed >= T::MaxContributorsProcessing::get() {
ContributorsFinalized::<T>::insert(campaign.id, processed);
return
}
}
ContributorsFinalized::<T>::insert(campaign.id, processed_offset + *processed);
ContributorsFinalized::<T>::insert(campaign.id, processed);
// TODO: This doesn't make sense without "transfer_amount" error handling
if *campaign_balance < campaign.cap {
let _ = Self::set_state(campaign.id, FlowState::Reverting, &campaign.org);
Expand Down Expand Up @@ -1009,24 +1012,25 @@ impl<T: Config> Pallet<T> {
}

fn revert_campaign(
block_number: &T::BlockNumber, processed: &mut u32,
block_number: &T::BlockNumber, total_processed: &mut u32,
campaign: &Campaign<T::Hash, T::AccountId, T::Balance, T::BlockNumber, Moment, BoundedVec<u8, T::StringLimit>>,
campaign_balance: &T::Balance, org_treasury: &T::AccountId,
contributors: &Vec<T::AccountId>
) {
let processed_offset = ContributorsReverted::<T>::get(campaign.id);
let offset: usize = usize::try_from(processed_offset).unwrap();
let mut processed = ContributorsReverted::<T>::get(campaign.id);
let offset: usize = usize::try_from(processed).unwrap();
for account in &contributors[offset..] {
let contribution = CampaignContribution::<T>::get((campaign.id, account.clone()));
T::Currency::unreserve(T::PaymentTokenId::get(), &account, contribution);

*processed += 1;
if *processed >= T::MaxContributorsProcessing::get() {
ContributorsReverted::<T>::insert(campaign.id, processed_offset + *processed);
*total_processed += 1;
processed += 1;
if *total_processed >= T::MaxContributorsProcessing::get() {
ContributorsReverted::<T>::insert(campaign.id, processed);
return
}
}
ContributorsReverted::<T>::insert(campaign.id, processed_offset + *processed);
ContributorsReverted::<T>::insert(campaign.id, processed);
// Unreserve Initial deposit
T::Currency::unreserve(T::ProtocolTokenId::get(), &org_treasury, campaign.deposit);

Expand Down
4 changes: 2 additions & 2 deletions flow/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,8 @@ impl gamedao_control::Config for Test {

parameter_types! {
pub const MinNameLength: u32 = 2;
pub const MaxCampaignsPerAddress: u32 = 3;
pub const MaxCampaignsPerBlock: u32 = 1;
pub const MaxCampaignsPerAddress: u32 = 2;
pub const MaxCampaignsPerBlock: u32 = 2;
pub const MaxCampaignsPerOrg: u32 = 64;
pub const MaxContributionsPerBlock: u32 = 3;
pub const MaxContributorsProcessing: u32 = 4;
Expand Down
37 changes: 36 additions & 1 deletion flow/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ fn flow_create_errors() {
Ok(())
}
));

assert_ok!(Flow::create_campaign(
Origin::signed(BOB), org, BOB, name.clone(), 20 * DOLLARS, 10 * DOLLARS,
current_block + 1, FlowProtocol::Raise, FlowGovernance::No,
empty_vec.clone(),
empty_vec.clone(),
empty_vec.clone(),
));
let block_campaigns_cnt = CampaignsByBlock::<Test>::get(current_block+1).len() as u32;
println!("Current limit is {:?} and max is {:?}", block_campaigns_cnt, <Test as Config>::MaxCampaignsPerBlock::get());
assert_noop!(
Expand Down Expand Up @@ -361,6 +369,7 @@ fn flow_on_finalize_campaign_succeess() {
let deposit = 10 * DOLLARS;
let contribution = 60 * DOLLARS;
let target = 500 * DOLLARS;
let init_acc_balance = 100 * DOLLARS;

// Create Campaign
let nonce = Nonce::<Test>::get();
Expand Down Expand Up @@ -389,6 +398,21 @@ fn flow_on_finalize_campaign_succeess() {
// Contribute (600/500)
assert_ok!(Flow::contribute(Origin::signed(ACC_10), campaign_id, contribution));

// Create second Campaign
let nonce = Nonce::<Test>::get();
let campaign_id_rev: H256 = <Test as frame_system::Config>::Hashing::hash_of(&nonce);
assert_ok!(Flow::create_campaign(
Origin::signed(BOB), org.clone(), BOB,
BoundedVec::truncate_from(vec![1, 2]),
target, deposit, expiry,
FlowProtocol::Raise, FlowGovernance::No,
BoundedVec::truncate_from(vec![1, 2]),
BoundedVec::truncate_from(vec![]),
BoundedVec::truncate_from(vec![]),
));
// Contribute (10/500)
assert_ok!(Flow::contribute(Origin::signed(ACC_1), campaign_id_rev, 10 * DOLLARS));

// --------- Block 0 (expiry): Schedule settlements ---------
System::set_block_number(expiry);
Flow::on_finalize(expiry);
Expand All @@ -399,6 +423,12 @@ fn flow_on_finalize_campaign_succeess() {
block_number: expiry,
}));

System::assert_has_event(Event::Flow(crate::Event::CampaignReverting {
campaign_id: campaign_id_rev,
campaign_balance: CampaignBalance::<Test>::get(campaign_id_rev),
block_number: expiry,
}));

// Ensure that campaign was scheduled to be finalized
assert_eq!(CampaignsByState::<Test>::get(&FlowState::Finalizing, &org), vec![campaign_id]);
// Ensure that campaign will be finalize in 3 blocks: 4 + 4 + 2
Expand All @@ -410,6 +440,7 @@ fn flow_on_finalize_campaign_succeess() {
Flow::on_initialize(expiry + 1);

assert_eq!(ContributorsFinalized::<Test>::get(campaign_id), batch_size as u32);
assert_eq!(ContributorsReverted::<Test>::get(campaign_id_rev), 0 as u32);
assert_eq!(
<Test as Config>::Currency::total_balance(PAYMENT_TOKEN_ID, &treasury),
batch_size * contribution
Expand All @@ -424,6 +455,7 @@ fn flow_on_finalize_campaign_succeess() {
Flow::on_initialize(expiry + 2);

assert_eq!(ContributorsFinalized::<Test>::get(campaign_id), batch_size as u32 * 2);
assert_eq!(ContributorsReverted::<Test>::get(campaign_id), 0 as u32);
assert_eq!(
<Test as Config>::Currency::total_balance(PAYMENT_TOKEN_ID, &treasury),
2 * batch_size * contribution
Expand All @@ -433,11 +465,14 @@ fn flow_on_finalize_campaign_succeess() {
0
);

// --------- Block 3: process last 2 contributors and finalize Campaign ---------
// --------- Block 3: process last 2 contributors and finalize Campaign1, process 1 contributor and revert Campaign2 ---------
System::set_block_number(expiry + 3);
Flow::on_initialize(expiry + 3);

assert_eq!(ContributorsFinalized::<Test>::get(campaign_id), total_contributors as u32);
assert_eq!(ContributorsReverted::<Test>::get(campaign_id_rev), 1 as u32);

// Campaign finalized:
let commission = <Test as Config>::CampaignFee::get().mul_floor(contribution * 10);
// The balance was transfered and locked in the org treasury
assert_eq!(
Expand Down