Skip to content

Commit

Permalink
Remove WAP
Browse files Browse the repository at this point in the history
  • Loading branch information
JuaniRios committed Feb 6, 2025
1 parent ede7645 commit f7ebd41
Show file tree
Hide file tree
Showing 19 changed files with 192 additions and 1,066 deletions.
52 changes: 19 additions & 33 deletions integration-tests/src/tests/e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,24 +158,20 @@ fn pre_wap_bids() -> Vec<(u32, [u8; 32], ParticipationMode, InvestorType, u64, f
]
}

fn wap() -> f64 {
10.30346708
}

#[allow(unused)]
fn post_wap_bids() -> Vec<(u32, [u8; 32], ParticipationMode, InvestorType, u64, f64, AcceptedFundingAsset, f64, f64)> {
// (bid_id, User, Participation mode, Investor type, CTs specified in extrinsic, CT Price, Participation Currency, Final participation currency ticket, PLMC bonded as a consequence)
vec![
(21, SAM, OTM, Professional, 2_000, 10.303467, USDT, 20_916.0382, 22_620.1253),
(22, SAM, OTM, Professional, 2_200, 10.303467, DOT, 4_947.8800, 24_882.1378),
(16, DAVE, OTM, Professional, 1_000, 10.303467, USDT, 10_458.0191, 11_310.0627),
(17, GERALT, Classic(15), Institutional, 500, 10.303467, USDT, 5_151.7335, 1_885.0104),
(18, GEORGE, Classic(20), Institutional, 1_900, 10.303467, USDT, 19_576.5875, 5_372.2798),
(19, GINO, Classic(25), Institutional, 600, 10.303467, USDT, 6_182.0802, 1_357.2075),
(20, STEVE, OTM, Professional, 1_000, 10.303467, USDT, 10_458.0191, 11_310.0627),
(0, BROCK, OTM, Professional, 700, 10.000000, USDC, 7_101.4493, 7_683.8639),
(1, BEN, OTM, Professional, 4_000, 10.000000, USDT, 40_600.0000, 43_907.7936),
(2, BILL, Classic(3), Professional, 3_000, 10.000000, USDC, 29_985.0075, 54_884.7420),
(21, SAM, OTM, Professional, 2_000, 12.0, USDT, 24000.0, 26344.6762),
(22, SAM, OTM, Professional, 2_200, 12.0, DOT, 5677.419355, 28979.1438),
(16, DAVE, OTM, Professional, 1_000, 11.0, USDT, 11000.0, 12074.6432),
(17, GERALT, Classic(15), Institutional, 500, 11.0, USDT, 5500.0, 2012.4405),
(18, GEORGE, Classic(20), Institutional, 1_900, 11.0, USDT, 20900.0, 5735.4555),
(19, GINO, Classic(25), Institutional, 600, 11.0, USDT, 6600.0, 1448.9572),
(20, STEVE, OTM, Professional, 1_000, 11.0, USDT, 11000.0, 12074.6432),
(0, BROCK, OTM, Professional, 700, 10.000000, USDC, 6996.501749, 7_683.8639),
(1, BEN, OTM, Professional, 4_000, 10.000000, USDT, 40_000.0, 43_907.7936),
(2, BILL, Classic(3), Professional, 3_000, 10.000000, USDC, 29985.0075, 54_884.7420),
(3, BRAD, Classic(6), Professional, 700, 10.000000, USDT, 7_000.0000, 6_403.2199),
(4, BROCK, Classic(9), Professional, 3_400, 10.000000, USDT, 34_000.0000, 20_734.2359),
(5, BLAIR, Classic(8), Professional, 1_000, 10.000000, USDT, 10_000.0000, 6_860.5928),
Expand All @@ -187,7 +183,7 @@ fn post_wap_bids() -> Vec<(u32, [u8; 32], ParticipationMode, InvestorType, u64,
(11, BELLA, Classic(1), Professional, 800, 10.000000, USDT, 8_000.0000, 43_907.7936),
(12, BRUCE, Classic(4), Institutional, 3_000, 10.000000, USDT, 30_000.0000, 41_163.5565),
(13, BRENT, Classic(1), Institutional, 8_000, 10.000000, USDT, 80_000.0000, 439_077.9363),
(14, DOUG, OTM, Institutional, 100, 10.000000, USDT, 1_015.0000, 5_488.4742),
(14, DOUG, OTM, Institutional, 100, 10.000000, USDT, 1000.0, 5_488.4742),
(15, DAVE, OTM, Professional, 0, 10.000000, USDT, 0.00, 0.00),
]
}
Expand All @@ -198,7 +194,7 @@ fn cts_minted() -> f64 {
}

fn usd_raised() -> f64 {
502_791.8972
513_400.0000
}

#[allow(unused)]
Expand All @@ -209,7 +205,7 @@ fn ct_fees() -> (f64, f64, f64) {

fn issuer_payouts() -> (f64, f64, f64) {
// (USDT, USDC, DOT)
(430_124.27, 36_981.51, 7_670.46)
(437_000.00, 36_981.51, 8_473.12)
}

fn evaluator_reward_pots() -> (f64, f64, f64, f64) {
Expand Down Expand Up @@ -245,17 +241,17 @@ fn final_payouts() -> Vec<([u8; 32], f64, f64)> {
(DAVE, 1059.661749, 0.00),
(MASON, 35.37757672, 0.00),
(MIKE, 82.74302164, 0.00),
(GERALT, 500.0, 1_885.01),
(GEORGE, 1_900.0, 5_372.28),
(GINO, 600.0, 1_357.21),
(GERALT, 500.0, 2_012.44),
(GEORGE, 1_900.0, 5_735.46),
(GINO, 600.0, 1_448.96),
(STEVE, 1017.159307, 0.0),
(SAM, 4267.09505, 0.0),
]
}

fn otm_fee_recipient_balances() -> (f64, f64, f64) {
// USDT, USDC, DOT
(1233.208025, 104.9475262, 73.12137929)
(1305.0, 104.9475262, 85.16129032)
}

fn otm_treasury_sub_account_plmc_held() -> f64 {
Expand Down Expand Up @@ -462,18 +458,6 @@ fn e2e_test() {

let project_details = inst.get_project_details(project_id);
let project_metadata = inst.get_project_metadata(project_id);
let stored_wap = project_details.weighted_average_price.unwrap();
let expected_wap = PriceProviderOf::<PolimecRuntime>::calculate_decimals_aware_price(
PriceOf::<PolimecRuntime>::from_float(wap()),
USD_DECIMALS,
CT_DECIMALS,
)
.unwrap();
assert_close_enough!(
stored_wap.saturating_mul_int(PLMC),
expected_wap.saturating_mul_int(PLMC),
Perquintill::from_float(0.9999)
);

let actual_cts_minted = polimec_runtime::ContributionTokens::total_issuance(project_id);
let expected_cts_minted = FixedU128::from_float(cts_minted()).saturating_mul_int(CT_UNIT);
Expand Down Expand Up @@ -544,6 +528,8 @@ fn e2e_test() {
);

for (user, ct_rewarded, plmc_bonded) in final_payouts() {
let names = names();

let user: PolimecAccountId = user.into();
let ct_rewarded = FixedU128::from_float(ct_rewarded).saturating_mul_int(CT_UNIT);
let plmc_bonded = FixedU128::from_float(plmc_bonded).saturating_mul_int(PLMC);
Expand Down
14 changes: 9 additions & 5 deletions pallets/funding/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,8 +771,8 @@ mod benchmarks {
}

// We have 3 logic paths
// 1 - Accepted bid with no refunds (i.e. final price <= WAP, no partial acceptance)
// 2 - Accepted bid with refund (i.e. final price > WAP or partial acceptance)
// 1 - Accepted bid with no refunds
// 2 - Accepted bid with refund (i.e. partially accepted bid )
// 3 - Rejected bid (i.e. bid not accepted, everything refunded, no CT/migration)
// Path 2 is the most expensive but not by far, so we only benchmark and charge for this weight
#[benchmark]
Expand All @@ -788,10 +788,15 @@ mod benchmarks {

let project_metadata = default_project_metadata::<T>(issuer.clone());
let increase = project_metadata.minimum_price * PriceOf::<T>::saturating_from_rational(5, 10);
let target_wap = project_metadata.minimum_price + increase;
let target_price = project_metadata.minimum_price + increase;

let mut new_bucket = Pallet::<T>::create_bucket_from_metadata(&project_metadata).unwrap();
new_bucket.current_price = target_price;
new_bucket.amount_left = new_bucket.delta_amount;


let evaluations = inst.generate_successful_evaluations(project_metadata.clone(), 10);
let bids = inst.generate_bids_that_take_price_to(project_metadata.clone(), target_wap);
let bids = inst.generate_bids_from_bucket(project_metadata.clone(), new_bucket, USDT);

let project_id =
inst.create_finished_project(project_metadata.clone(), issuer, None, evaluations, bids.clone());
Expand Down Expand Up @@ -829,7 +834,6 @@ mod benchmarks {
id: bid_to_settle.id,
status: bid_to_settle.status,
final_ct_amount: expected_ct_amount,
final_ct_usd_price: bid_to_settle.original_ct_usd_price,
}
.into(),
);
Expand Down
1 change: 0 additions & 1 deletion pallets/funding/src/functions/1_application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ impl<T: Config> Pallet<T> {
issuer_account: issuer.clone(),
issuer_did: did.clone(),
is_frozen: false,
weighted_average_price: None,
fundraising_target_usd: fundraising_target,
status: ProjectStatus::Application,
round_duration: BlockNumberPair::new(None, None),
Expand Down
2 changes: 1 addition & 1 deletion pallets/funding/src/functions/3_auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<T: Config> Pallet<T> {
};

BidBucketBounds::<T>::mutate(project_id, current_bucket.current_price, |maybe_indexes| {
if let Some((i, j)) = maybe_indexes {
if let Some((i, _j)) = maybe_indexes {
*maybe_indexes = Some((*i, bid_id));
} else {
*maybe_indexes = Some((bid_id, bid_id));
Expand Down
4 changes: 1 addition & 3 deletions pallets/funding/src/functions/5_funding_end.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ impl<T: Config> Pallet<T> {
ProjectsInAuctionRound::<T>::put(WeakBoundedVec::force_from(project_ids, None));

let auction_allocation_size = project_metadata.total_allocation_size;
let weighted_average_price = bucket.calculate_wap(auction_allocation_size);
project_details.weighted_average_price = Some(weighted_average_price);

let bucket_price_higher_than_initial = bucket.current_price > bucket.initial_price;
let sold_percent =
Expand All @@ -39,7 +37,7 @@ impl<T: Config> Pallet<T> {

DidWithActiveProjects::<T>::set(issuer_did, None);

let usd_raised = Self::calculate_usd_sold_from_bucket(bucket.clone(), project_metadata.total_allocation_size);
let usd_raised = bucket.calculate_usd_raised(auction_allocation_size);
project_details.funding_amount_reached_usd = usd_raised;
project_details.remaining_contribution_tokens =
if bucket.current_price == bucket.initial_price { bucket.amount_left } else { Zero::zero() };
Expand Down
50 changes: 23 additions & 27 deletions pallets/funding/src/functions/6_settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ impl<T: Config> Pallet<T> {
let project_metadata = ProjectsMetadata::<T>::get(project_id).ok_or(Error::<T>::ProjectMetadataNotFound)?;
let funding_success =
matches!(project_details.status, ProjectStatus::SettlementStarted(FundingOutcome::Success));
let wap = project_details.weighted_average_price.unwrap_or(project_metadata.minimum_price);
let mut bid = Bids::<T>::get((project_id, bid_id)).ok_or(Error::<T>::ParticipationNotFound)?;

ensure!(
Expand All @@ -173,8 +172,8 @@ impl<T: Config> Pallet<T> {

// Return the full bid amount to refund if bid is rejected or project failed,
// Return a partial amount if the project succeeded, and the wap > paid price or bid is partially accepted
let BidRefund { final_ct_usd_price, final_ct_amount, refunded_plmc, refunded_funding_asset_amount } =
Self::calculate_refund(&bid, funding_success, wap)?;
let BidRefund { final_ct_amount, refunded_plmc, refunded_funding_asset_amount } =
Self::calculate_refund(&bid, funding_success)?;

Self::release_funding_asset(project_id, &bid.bidder, refunded_funding_asset_amount, bid.funding_asset)?;

Expand Down Expand Up @@ -227,42 +226,39 @@ impl<T: Config> Pallet<T> {
id: bid.id,
status: bid.status,
final_ct_amount,
final_ct_usd_price,
});

Ok(())
}

/// Calculate the amount of funds the bidder should receive back based on the original bid
/// amount and price compared to the final bid amount and price.
fn calculate_refund(
bid: &BidInfoOf<T>,
funding_success: bool,
wap: PriceOf<T>,
) -> Result<BidRefund<T>, DispatchError> {
let final_ct_usd_price = if bid.original_ct_usd_price > wap { wap } else { bid.original_ct_usd_price };
fn calculate_refund(bid: &BidInfoOf<T>, funding_success: bool) -> Result<BidRefund, DispatchError> {
let multiplier: MultiplierOf<T> = bid.mode.multiplier().try_into().map_err(|_| Error::<T>::BadMath)?;
if !funding_success || bid.status == BidStatus::Rejected {
return Ok(BidRefund::<T> {
final_ct_usd_price,
let ct_price = bid.original_ct_usd_price;

match bid.status {
BidStatus::Accepted if funding_success => Ok(BidRefund {
final_ct_amount: bid.original_ct_amount,
refunded_plmc: Zero::zero(),
refunded_funding_asset_amount: Zero::zero(),
}),
BidStatus::PartiallyAccepted(accepted_amount) if funding_success => {
let new_ticket_size = ct_price.checked_mul_int(accepted_amount).ok_or(Error::<T>::BadMath)?;
let new_plmc_bond = Self::calculate_plmc_bond(new_ticket_size, multiplier)?;
let new_funding_asset_amount =
Self::calculate_funding_asset_amount(new_ticket_size, bid.funding_asset)?;
let refunded_plmc = bid.plmc_bond.saturating_sub(new_plmc_bond);
let refunded_funding_asset_amount =
bid.funding_asset_amount_locked.saturating_sub(new_funding_asset_amount);
Ok(BidRefund { final_ct_amount: accepted_amount, refunded_plmc, refunded_funding_asset_amount })
},
_ => Ok(BidRefund {
final_ct_amount: Zero::zero(),
refunded_plmc: bid.plmc_bond,
refunded_funding_asset_amount: bid.funding_asset_amount_locked,
});
}),
}
let final_ct_amount = match bid.status {
BidStatus::Accepted => bid.original_ct_amount,
BidStatus::PartiallyAccepted(accepted_amount) => accepted_amount,
_ => Zero::zero(),
};

let new_ticket_size = final_ct_usd_price.checked_mul_int(final_ct_amount).ok_or(Error::<T>::BadMath)?;
let new_plmc_bond = Self::calculate_plmc_bond(new_ticket_size, multiplier)?;
let new_funding_asset_amount = Self::calculate_funding_asset_amount(new_ticket_size, bid.funding_asset)?;
let refunded_plmc = bid.plmc_bond.saturating_sub(new_plmc_bond);
let refunded_funding_asset_amount = bid.funding_asset_amount_locked.saturating_sub(new_funding_asset_amount);

Ok(BidRefund::<T> { final_ct_usd_price, final_ct_amount, refunded_plmc, refunded_funding_asset_amount })
}

pub fn do_mark_project_as_settled(project_id: ProjectId) -> DispatchResult {
Expand Down
38 changes: 0 additions & 38 deletions pallets/funding/src/functions/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,44 +456,6 @@ impl<T: Config> Pallet<T> {
let funding_asset_decimals = T::FundingCurrency::decimals(funding_asset_id.clone());
<PriceProviderOf<T>>::get_decimals_aware_price(funding_asset_id, USD_DECIMALS, funding_asset_decimals)
}

pub fn calculate_usd_sold_from_bucket(mut bucket: BucketOf<T>, auction_allocation_size: Balance) -> Balance {
if bucket.current_price == bucket.initial_price {
return bucket.initial_price.saturating_mul_int(auction_allocation_size.saturating_sub(bucket.amount_left))
}

let mut total_usd_sold = 0u128;
let wap = bucket.calculate_wap(auction_allocation_size);

let mut total_ct_amount_left = auction_allocation_size;

// Latest bucket will be partially sold
let ct_sold = bucket.delta_amount.saturating_sub(bucket.amount_left);
let usd_sold = wap.saturating_mul_int(ct_sold);
total_usd_sold = total_usd_sold.saturating_add(usd_sold);
total_ct_amount_left = total_ct_amount_left.saturating_sub(ct_sold);
bucket.current_price = bucket.current_price.saturating_sub(bucket.delta_price);

while total_ct_amount_left > 0 {
// If we reached the inital bucket, all the CTs remaining are taken from this bucket
if bucket.current_price == bucket.initial_price {
let ct_sold = total_ct_amount_left;
let usd_sold = bucket.initial_price.saturating_mul_int(ct_sold);
total_usd_sold = total_usd_sold.saturating_add(usd_sold);
break
}

let price_charged = wap.min(bucket.current_price);
let ct_sold = total_ct_amount_left.min(bucket.delta_amount);
let usd_raised = price_charged.saturating_mul_int(ct_sold);
total_usd_sold = total_usd_sold.saturating_add(usd_raised);
total_ct_amount_left = total_ct_amount_left.saturating_sub(ct_sold);

bucket.current_price = bucket.current_price.saturating_sub(bucket.delta_price);
}

total_usd_sold
}
}

pub mod typed_data_v4 {
Expand Down
Loading

0 comments on commit f7ebd41

Please sign in to comment.