Skip to content

Commit

Permalink
Merge pull request #66 from Polimec/feature/plmc-240-implement-automa…
Browse files Browse the repository at this point in the history
…tic-funding-payout-to-issuer-for-bids

Feature/plmc 240 implement automatic funding payout to issuer for bids
  • Loading branch information
lrazovic authored Aug 14, 2023
2 parents 8f1c766 + 260c27c commit dd52387
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 19 deletions.
45 changes: 41 additions & 4 deletions pallets/funding/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1517,11 +1517,48 @@ impl<T: Config> Pallet<T> {
}

pub fn do_payout_bid_funds_for(
_caller: AccountIdOf<T>,
_project_id: T::ProjectIdentifier,
_bidder: AccountIdOf<T>,
_bid_id: StorageItemIdOf<T>,
caller: AccountIdOf<T>,
project_id: T::ProjectIdentifier,
bidder: AccountIdOf<T>,
bid_id: StorageItemIdOf<T>,
) -> Result<(), DispatchError> {
// * Get variables *
let project_details = ProjectsDetails::<T>::get(project_id).ok_or(Error::<T>::ProjectInfoNotFound)?;
let mut bid = Bids::<T>::get((project_id, bidder.clone(), bid_id)).ok_or(Error::<T>::BidNotFound)?;

// * Validity checks *
ensure!(
project_details.status == ProjectStatus::FundingSuccessful &&
matches!(bid.status, BidStatus::Accepted | BidStatus::PartiallyAccepted(..)),
Error::<T>::NotAllowed
);

// * Calculate variables *
let issuer = project_details.issuer;
let project_pot = Self::fund_account_id(project_id);
let payout_amount = bid.funding_asset_amount_locked;
let payout_asset = bid.funding_asset;

// * Update storage *
T::FundingCurrency::transfer(
payout_asset.to_statemint_id(),
&project_pot,
&issuer,
payout_amount,
Preservation::Expendable,
)?;
bid.funds_released = true;
Bids::<T>::insert((project_id, bidder.clone(), bid_id), bid);

// * Emit events *
Self::deposit_event(Event::<T>::BidFundingPaidOut {
project_id,
bidder: bidder.clone(),
id: bid_id,
amount: payout_amount,
caller,
});

Ok(())
}
}
Expand Down
11 changes: 2 additions & 9 deletions pallets/funding/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -600,7 +600,7 @@ fn issuer_funding_payout_one_bid<T: Config>(project_id: T::ProjectIdentifier) ->

let mut remaining_bids = project_bids.filter(|bid| !bid.funds_released);

if let Some(mut bid) = remaining_bids.next() {
if let Some(bid) = remaining_bids.next() {
match Pallet::<T>::do_payout_bid_funds_for(
T::PalletId::get().into_account_truncating(),
bid.project_id,
Expand All @@ -615,14 +615,7 @@ fn issuer_funding_payout_one_bid<T: Config>(project_id: T::ProjectIdentifier) ->
error: e,
}),
};

bid.funds_released = true;

Bids::<T>::insert((project_id, bid.bidder.clone(), bid.id), bid);

// (Weight::zero(), remaining_bids.count() as u64)
// TODO: Remove this when function is implemented
(Weight::zero(), 0u64)
(Weight::zero(), remaining_bids.count() as u64)
} else {
(Weight::zero(), 0u64)
}
Expand Down
7 changes: 7 additions & 0 deletions pallets/funding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,13 @@ pub mod pallet {
amount: BalanceOf<T>,
caller: AccountIdOf<T>,
},
BidFundingPaidOut {
project_id: ProjectIdOf<T>,
bidder: AccountIdOf<T>,
id: StorageItemIdOf<T>,
amount: BalanceOf<T>,
caller: AccountIdOf<T>,
},
}

#[pallet::error]
Expand Down
85 changes: 79 additions & 6 deletions pallets/funding/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2903,7 +2903,7 @@ mod auction_round_success {

let auctioning_project = AuctioningProject::new_with(&test_env, project, issuer, evaluations);
let mut bidders_plmc = calculate_auction_plmc_spent(bids.clone());
bidders_plmc.iter_mut().for_each(|(acc, amount)| *amount += get_ed());
bidders_plmc.iter_mut().for_each(|(_acc, amount)| *amount += get_ed());
test_env.mint_plmc_to(bidders_plmc.clone());

let bidders_funding_assets = calculate_auction_funding_asset_spent(bids.clone());
Expand All @@ -2914,7 +2914,7 @@ mod auction_round_success {
let community_funding_project = auctioning_project.start_community_funding();
let final_price = community_funding_project.get_project_details().weighted_average_price.unwrap();
let mut contributors_plmc = calculate_contributed_plmc_spent(community_contributions.clone(), final_price);
contributors_plmc.iter_mut().for_each(|(acc, amount)| *amount += get_ed());
contributors_plmc.iter_mut().for_each(|(_acc, amount)| *amount += get_ed());
test_env.mint_plmc_to(contributors_plmc.clone());

let contributors_funding_assets =
Expand Down Expand Up @@ -2953,6 +2953,79 @@ mod auction_round_success {
.is_some();
assert!(!schedule_exists);
}

#[test]
pub fn bid_funding_assets_are_paid_automatically_to_issuer() {
let test_env = TestEnvironment::new();
let project = default_project(test_env.get_new_nonce());
let issuer = ISSUER;
let evaluations = default_evaluations();
let bids = generate_bids_from_total_usd(project.total_allocation_size, project.minimum_price);
let community_contributions = vec![];
let remainder_contributions = vec![];

let finished_project = FinishedProject::new_with(
&test_env,
project,
issuer,
evaluations,
bids,
community_contributions,
remainder_contributions,
);
let project_id = finished_project.get_project_id();
let final_bid_payouts = test_env.in_ext(|| {
Bids::<TestRuntime>::iter_prefix_values((finished_project.project_id,))
.map(|bid| (bid.bidder, bid.funding_asset_amount_locked, bid.funding_asset.to_statemint_id()))
.collect::<UserToStatemintAsset>()
});
let total_expected_bid_payout =
final_bid_payouts.iter().map(|bid| bid.1.clone()).sum::<BalanceOf<TestRuntime>>();

let prev_issuer_funding_balance =
test_env.get_free_statemint_asset_balances_for(final_bid_payouts[0].2, vec![issuer.clone()])[0].1;
let prev_bidders_funding_balances = test_env.get_free_statemint_asset_balances_for(
final_bid_payouts[0].2,
final_bid_payouts.iter().map(|(acc, _, _)| acc.clone()).collect::<Vec<_>>(),
);
let prev_total_bidder_balance =
prev_bidders_funding_balances.iter().map(|(_, balance, _)| balance).sum::<BalanceOf<TestRuntime>>();
let prev_project_pot_funding_balance = test_env.get_free_statemint_asset_balances_for(
final_bid_payouts[0].2,
vec![Pallet::<TestRuntime>::fund_account_id(project_id)],
)[0]
.1;

test_env.advance_time(<TestRuntime as Config>::SuccessToSettlementTime::get() + 1).unwrap();
assert_eq!(
finished_project.get_project_details().cleanup,
Cleaner::Success(CleanerState::Finished(PhantomData))
);

let post_issuer_funding_balance =
test_env.get_free_statemint_asset_balances_for(final_bid_payouts[0].2, vec![issuer.clone()])[0].1;
let post_bidders_funding_balances = test_env.get_free_statemint_asset_balances_for(
final_bid_payouts[0].2,
final_bid_payouts.iter().map(|(acc, _, _)| acc.clone()).collect::<Vec<_>>(),
);
let post_total_bidder_balance =
post_bidders_funding_balances.iter().map(|(_, balance, _)| balance).sum::<BalanceOf<TestRuntime>>();
let post_project_pot_funding_balance = test_env.get_free_statemint_asset_balances_for(
final_bid_payouts[0].2,
vec![Pallet::<TestRuntime>::fund_account_id(project_id)],
)[0]
.1;

let issuer_funding_delta = post_issuer_funding_balance - prev_issuer_funding_balance;
let project_pot_funding_delta = prev_project_pot_funding_balance - post_project_pot_funding_balance;

assert_eq!(issuer_funding_delta, total_expected_bid_payout);
assert_eq!(issuer_funding_delta, project_pot_funding_delta);

assert_eq!(prev_total_bidder_balance, 0u128);
assert_eq!(post_total_bidder_balance, 0u128);
assert_eq!(post_project_pot_funding_balance, 0u128);
}
}

mod auction_round_failure {
Expand Down Expand Up @@ -4975,9 +5048,9 @@ mod remainder_round_success {

let merged_plmc_balances = generic_map_merge_reduce(
vec![contributed_plmc_balances.clone(), bid_plmc_balances.clone()],
|(account, amount)| account.clone(),
|(account, _amount)| account.clone(),
BalanceOf::<TestRuntime>::zero(),
|(account, amount), total| total + amount,
|(_account, amount), total| total + amount,
);
test_env.advance_time((1 * DAYS + 1u32).into()).unwrap();

Expand Down Expand Up @@ -5044,9 +5117,9 @@ mod remainder_round_success {

let merged_plmc_balances = generic_map_merge_reduce(
vec![contributed_plmc_balances.clone(), bid_plmc_balances.clone()],
|(account, amount)| account.clone(),
|(account, _amount)| account.clone(),
BalanceOf::<TestRuntime>::zero(),
|(account, amount), total| total + amount,
|(_account, amount), total| total + amount,
);

for (contributor, amount) in merged_plmc_balances {
Expand Down

0 comments on commit dd52387

Please sign in to comment.