Skip to content

Commit

Permalink
new decimals community test
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed May 1, 2024
1 parent 7c8f2f1 commit c15e2fc
Show file tree
Hide file tree
Showing 5 changed files with 192 additions and 30 deletions.
3 changes: 1 addition & 2 deletions nodes/parachain/src/chain_spec/polimec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,7 @@ pub fn get_rococo_chain_spec() -> GenericChainSpec {
}

fn base_testnet_genesis(
#[allow(unused)]
stakers: Vec<(AccountId, Option<AccountId>, Balance)>,
#[allow(unused)] stakers: Vec<(AccountId, Option<AccountId>, Balance)>,
inflation_config: InflationInfo<Balance>,
initial_authorities: Vec<AccountId>,
endowed_accounts: Vec<(AccountId, Balance)>,
Expand Down
3 changes: 1 addition & 2 deletions nodes/parachain/src/chain_spec/politest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,7 @@ pub fn get_live_chain_spec() -> GenericChainSpec {

#[allow(clippy::too_many_arguments)]
fn testnet_genesis(
#[allow(unused)]
stakers: Vec<(AccountId, Option<AccountId>, Balance)>,
#[allow(unused)] stakers: Vec<(AccountId, Option<AccountId>, Balance)>,
inflation_config: InflationInfo<Balance>,
initial_authorities: Vec<AccountId>,
mut endowed_accounts: Vec<(AccountId, Balance)>,
Expand Down
5 changes: 3 additions & 2 deletions pallets/funding/src/instantiator/chain_interactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -538,11 +538,12 @@ impl<
evaluations: Vec<UserToUSDBalance<T>>,
bids: Vec<BidParams<T>>,
) -> ProjectId {
let project_id = self.create_auctioning_project(project_metadata.clone(), issuer, evaluations.clone());
if bids.is_empty() {
panic!("Cannot start community funding without bids")
self.start_community_funding(project_id).unwrap();
return project_id
}

let project_id = self.create_auctioning_project(project_metadata.clone(), issuer, evaluations.clone());
let bidders = bids.accounts();
let asset_id = bids[0].asset.to_assethub_id();
let prev_plmc_balances = self.get_free_plmc_balances_for(bidders.clone());
Expand Down
53 changes: 29 additions & 24 deletions pallets/funding/src/tests/3_auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@ mod round_flow {

#[cfg(test)]
mod success {
use std::collections::HashSet;
use super::*;
use frame_support::traits::fungibles::metadata::Inspect;
use sp_core::bounded_vec;
use std::ops::Not;
use std::{collections::HashSet, ops::Not};

#[test]
fn auction_round_completed() {
Expand Down Expand Up @@ -530,46 +529,44 @@ mod round_flow {
USD_DECIMALS,
default_project_metadata.token_information.decimals,
)
.unwrap();
.unwrap();
let usable_plmc_price = inst.execute(|| {
<TestRuntime as Config>::PriceProvider::get_decimals_aware_price(
PLMC_FOREIGN_ID,
USD_DECIMALS,
PLMC_DECIMALS,
)
.unwrap()
.unwrap()
});
let usdt_price = inst.execute(|| {
<TestRuntime as Config>::PriceProvider::get_decimals_aware_price(
AcceptedFundingAsset::USDT.to_assethub_id(),
USD_DECIMALS,
ForeignAssets::decimals(AcceptedFundingAsset::USDT.to_assethub_id()),
)
.unwrap()
.unwrap()
});
let usdc_price = inst.execute(|| {
<TestRuntime as Config>::PriceProvider::get_decimals_aware_price(
AcceptedFundingAsset::USDC.to_assethub_id(),
USD_DECIMALS,
ForeignAssets::decimals(AcceptedFundingAsset::USDC.to_assethub_id()),
)
.unwrap()
.unwrap()
});
let dot_price = inst.execute(|| {
<TestRuntime as Config>::PriceProvider::get_decimals_aware_price(
AcceptedFundingAsset::DOT.to_assethub_id(),
USD_DECIMALS,
ForeignAssets::decimals(AcceptedFundingAsset::DOT.to_assethub_id()),
)
.unwrap()
.unwrap()
});


let mut funding_assets_cycle = vec![
AcceptedFundingAsset::USDT,
AcceptedFundingAsset::USDC,
AcceptedFundingAsset::DOT,
].into_iter().cycle();
let mut funding_assets_cycle =
vec![AcceptedFundingAsset::USDT, AcceptedFundingAsset::USDC, AcceptedFundingAsset::DOT]
.into_iter()
.cycle();

let mut min_bid_amounts_ct = Vec::new();
let mut min_bid_amounts_usd = Vec::new();
Expand All @@ -594,7 +591,7 @@ mod round_flow {
USD_DECIMALS,
decimals,
)
.unwrap();
.unwrap();

dbg!(original_price);
dbg!(project_metadata.minimum_price);
Expand All @@ -603,7 +600,11 @@ mod round_flow {
project_metadata.participation_currencies = bounded_vec!(funding_asset);

let issuer: AccountIdOf<TestRuntime> = (10_000 + inst.get_new_nonce()).try_into().unwrap();
let evaluations = inst.generate_successful_evaluations(project_metadata.clone(), default_evaluators(), default_weights());
let evaluations = inst.generate_successful_evaluations(
project_metadata.clone(),
default_evaluators(),
default_weights(),
);
let project_id = inst.create_auctioning_project(project_metadata.clone(), issuer, evaluations);

let auction_allocation_percentage = project_metadata.auction_round_allocation_percentage;
Expand All @@ -614,21 +615,27 @@ mod round_flow {
let auction_allocation_usd = project_metadata.minimum_price.saturating_mul_int(auction_allocation_ct);
auction_allocations_usd.push(auction_allocation_usd);



let min_professional_bid_usd = project_metadata.bidding_ticket_sizes.professional.usd_minimum_per_participation.unwrap();
let min_professional_bid_usd =
project_metadata.bidding_ticket_sizes.professional.usd_minimum_per_participation.unwrap();
min_bid_amounts_usd.push(min_professional_bid_usd);
let min_professional_bid_ct = project_metadata.minimum_price.reciprocal().unwrap().saturating_mul_int(min_professional_bid_usd);
let min_professional_bid_plmc = usable_plmc_price.reciprocal().unwrap().saturating_mul_int(min_professional_bid_usd);
let min_professional_bid_ct =
project_metadata.minimum_price.reciprocal().unwrap().saturating_mul_int(min_professional_bid_usd);
let min_professional_bid_plmc =
usable_plmc_price.reciprocal().unwrap().saturating_mul_int(min_professional_bid_usd);
min_bid_amounts_ct.push(min_professional_bid_ct);
let min_professional_bid_funding_asset = funding_asset_usd_price.reciprocal().unwrap().saturating_mul_int(min_professional_bid_usd);
let min_professional_bid_funding_asset =
funding_asset_usd_price.reciprocal().unwrap().saturating_mul_int(min_professional_bid_usd);

// Every project should want to raise 5MM USD on the auction round regardless of CT decimals
assert_eq!(auction_allocation_usd, 5_000_000 * USD_UNIT);

// A minimum bid goes through. This is a fixed USD value, but the extrinsic amount depends on CT decimals.
inst.mint_plmc_to(vec![UserToPLMCBalance::new(BIDDER_1, min_professional_bid_plmc + ed)]);
inst.mint_foreign_asset_to(vec![UserToForeignAssets::new(BIDDER_1, min_professional_bid_funding_asset, funding_asset.to_assethub_id())]);
inst.mint_foreign_asset_to(vec![UserToForeignAssets::new(
BIDDER_1,
min_professional_bid_funding_asset,
funding_asset.to_assethub_id(),
)]);

dbg!(&min_professional_bid_funding_asset);
dbg!(&min_professional_bid_usd);
Expand All @@ -652,8 +659,6 @@ mod round_flow {
// The bucket should have 1MM * 10^decimals CT minus what we just bid
let bucket = inst.execute(|| Buckets::<TestRuntime>::get(project_id).unwrap());
assert_eq!(bucket.amount_left, 500_000u128 * 10u128.pow(decimals as u32) - min_professional_bid_ct);


};

for decimals in 0..25 {
Expand Down
158 changes: 158 additions & 0 deletions pallets/funding/src/tests/4_community.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ mod round_flow {
#[cfg(test)]
mod success {
use super::*;
use frame_support::traits::fungibles::metadata::Inspect;
use sp_runtime::bounded_vec;
use std::collections::HashSet;

#[test]
fn community_round_completed() {
Expand Down Expand Up @@ -151,6 +154,161 @@ mod round_flow {

assert_eq!(inst.get_project_details(project_id).remaining_contribution_tokens, 0);
}

#[test]
fn different_decimals_ct_works_as_expected() {
// Setup some base values to compare different decimals
let mut inst = MockInstantiator::new(Some(RefCell::new(new_test_ext())));
let ed = inst.get_ed();
let default_project_metadata = default_project_metadata(ISSUER_1);
let original_decimal_aware_price = default_project_metadata.minimum_price;
let original_price = <TestRuntime as Config>::PriceProvider::convert_back_to_normal_price(
original_decimal_aware_price,
USD_DECIMALS,
default_project_metadata.token_information.decimals,
)
.unwrap();
let usable_plmc_price = inst.execute(|| {
<TestRuntime as Config>::PriceProvider::get_decimals_aware_price(
PLMC_FOREIGN_ID,
USD_DECIMALS,
PLMC_DECIMALS,
)
.unwrap()
});
let usdt_price = inst.execute(|| {
<TestRuntime as Config>::PriceProvider::get_decimals_aware_price(
AcceptedFundingAsset::USDT.to_assethub_id(),
USD_DECIMALS,
ForeignAssets::decimals(AcceptedFundingAsset::USDT.to_assethub_id()),
)
.unwrap()
});
let usdc_price = inst.execute(|| {
<TestRuntime as Config>::PriceProvider::get_decimals_aware_price(
AcceptedFundingAsset::USDC.to_assethub_id(),
USD_DECIMALS,
ForeignAssets::decimals(AcceptedFundingAsset::USDC.to_assethub_id()),
)
.unwrap()
});
let dot_price = inst.execute(|| {
<TestRuntime as Config>::PriceProvider::get_decimals_aware_price(
AcceptedFundingAsset::DOT.to_assethub_id(),
USD_DECIMALS,
ForeignAssets::decimals(AcceptedFundingAsset::DOT.to_assethub_id()),
)
.unwrap()
});

let mut funding_assets_cycle =
vec![AcceptedFundingAsset::USDT, AcceptedFundingAsset::USDC, AcceptedFundingAsset::DOT]
.into_iter()
.cycle();

let mut total_fundings_ct = Vec::new();
let mut total_fundings_usd = Vec::new();
let mut total_fundings_plmc = Vec::new();

let mut decimal_test = |decimals: u8| {
let funding_asset = funding_assets_cycle.next().unwrap();
dbg!(&funding_asset);
let funding_asset_usd_price = match funding_asset {
AcceptedFundingAsset::USDT => usdt_price,
AcceptedFundingAsset::USDC => usdc_price,
AcceptedFundingAsset::DOT => dot_price,
};

dbg!(decimals);
let mut project_metadata = default_project_metadata.clone();
project_metadata.token_information.decimals = decimals;
project_metadata.minimum_price =
<TestRuntime as Config>::PriceProvider::calculate_decimals_aware_price(
original_price,
USD_DECIMALS,
decimals,
)
.unwrap();

dbg!(original_price);
dbg!(project_metadata.minimum_price);
project_metadata.total_allocation_size = 1_000_000 * 10u128.pow(decimals as u32);
project_metadata.mainnet_token_max_supply = project_metadata.total_allocation_size;
project_metadata.participation_currencies = bounded_vec!(funding_asset);

let issuer: AccountIdOf<TestRuntime> = (10_000 + inst.get_new_nonce()).try_into().unwrap();
let evaluations = inst.generate_successful_evaluations(
project_metadata.clone(),
default_evaluators(),
default_weights(),
);
let project_id =
inst.create_community_contributing_project(project_metadata.clone(), issuer, evaluations, vec![]);

let total_funding_ct = project_metadata.total_allocation_size;
let total_funding_usd = project_metadata.minimum_price.saturating_mul_int(total_funding_ct);
let total_funding_plmc = usable_plmc_price.reciprocal().unwrap().saturating_mul_int(total_funding_usd);
let total_funding_funding_asset =
funding_asset_usd_price.reciprocal().unwrap().saturating_mul_int(total_funding_usd);

total_fundings_ct.push(total_funding_ct);
total_fundings_usd.push(total_funding_usd);
total_fundings_plmc.push(total_funding_plmc);

// Every project should want to raise 10MM USD
assert_eq!(total_funding_usd, 10_000_000 * USD_UNIT);

// Every project should produce an 84MM PLMC bond when having the full funding at multiplier 1.
assert_eq!(total_funding_plmc, 84_000_000 * PLMC);

// Every project should have a different amount of CTs to raise, depending on their decimals
assert_eq!(total_funding_ct, 1_000_000 * 10u128.pow(decimals as u32));

// A minimum bid goes through. This is a fixed USD value, but the extrinsic amount depends on CT decimals.
inst.mint_plmc_to(vec![UserToPLMCBalance::new(BIDDER_1, total_funding_plmc + ed)]);
inst.mint_foreign_asset_to(vec![UserToForeignAssets::new(
BIDDER_1,
total_funding_funding_asset,
funding_asset.to_assethub_id(),
)]);

assert_ok!(inst.execute(|| PolimecFunding::community_contribute(
RuntimeOrigin::signed(BUYER_1),
get_mock_jwt_with_cid(
BUYER_1,
InvestorType::Retail,
generate_did_from_account(BUYER_1),
project_metadata.clone().policy_ipfs_cid.unwrap()
),
project_id,
total_funding_ct,
1u8.try_into().unwrap(),
funding_asset,
)));

// the remaining tokens should be zero
assert_eq!(inst.get_project_details(project_id).remaining_contribution_tokens, 0);

// We can successfully finish the project
inst.finish_funding(project_id).unwrap();
};

for decimals in 0..25 {
decimal_test(decimals);
}

// Since we use the same original price and allocation size and adjust for decimals,
// the USD and PLMC amounts should be the same
assert!(total_fundings_usd.iter().all(|x| *x == total_fundings_usd[0]));
assert!(total_fundings_plmc.iter().all(|x| *x == total_fundings_plmc[0]));

// CT amounts however should be different from each other
let mut hash_set_1 = HashSet::new();
for amount in total_fundings_ct {
assert!(!hash_set_1.contains(&amount));
hash_set_1.insert(amount);
}
}
}
}

Expand Down

0 comments on commit c15e2fc

Please sign in to comment.