From 363ef64910d6af52113e11dcbe1d664e7bda9a9a Mon Sep 17 00:00:00 2001 From: brooksjeremy7 <92278656+brooksjeremy7@users.noreply.github.com> Date: Tue, 24 Jun 2025 12:14:12 -0700 Subject: [PATCH 1/2] fix: calculations now sum all numerators and divide by a given denominator one time --- .../conditional_vault/src/instructions/redeem_tokens.rs | 9 +++++---- .../conditional_vault/src/state/conditional_vault.rs | 9 ++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/programs/conditional_vault/src/instructions/redeem_tokens.rs b/programs/conditional_vault/src/instructions/redeem_tokens.rs index 25ef7cefd..b116b5562 100644 --- a/programs/conditional_vault/src/instructions/redeem_tokens.rs +++ b/programs/conditional_vault/src/instructions/redeem_tokens.rs @@ -40,7 +40,7 @@ impl<'info, 'c: 'info> InteractWithVault<'info> { .max() .unwrap(); - let mut total_redeemable = 0; + let mut total_numerator: u128 = 0; for (conditional_mint, user_conditional_token_account) in conditional_token_mints .iter() @@ -53,9 +53,8 @@ impl<'info, 'c: 'info> InteractWithVault<'info> { .position(|mint| mint == &conditional_mint.key()) .unwrap(); - total_redeemable += ((user_conditional_token_account.amount as u128 - * question.payout_numerators[payout_index] as u128) - / question.payout_denominator as u128) as u64; + total_numerator += user_conditional_token_account.amount as u128 + * question.payout_numerators[payout_index] as u128; token::burn( CpiContext::new( @@ -70,6 +69,8 @@ impl<'info, 'c: 'info> InteractWithVault<'info> { )?; } + let total_redeemable = (total_numerator / question.payout_denominator as u128) as u64; + token::transfer( CpiContext::new_with_signer( accs.token_program.to_account_info(), diff --git a/programs/conditional_vault/src/state/conditional_vault.rs b/programs/conditional_vault/src/state/conditional_vault.rs index 33396d4e0..64692e24a 100644 --- a/programs/conditional_vault/src/state/conditional_vault.rs +++ b/programs/conditional_vault/src/state/conditional_vault.rs @@ -40,18 +40,21 @@ impl ConditionalVault { // tokens than the sum of the conditional token mint's supplies multiplied // by their respective payouts + let max_possible_liability = if !question.is_resolved() { // safe because conditional_token_supplies is non-empty *conditional_token_supplies.iter().max().unwrap() } else { - conditional_token_supplies + // Sum all numerators first, then divide once + let total_numerator: u128 = conditional_token_supplies .iter() .enumerate() .map(|(i, supply)| { *supply as u128 * question.payout_numerators[i] as u128 - / question.payout_denominator as u128 }) - .sum::() as u64 + .sum(); + + (total_numerator / question.payout_denominator as u128) as u64 }; require_gte!( From dc2a7cdcaba52d30411ebe1bd899786320fe8c62 Mon Sep 17 00:00:00 2001 From: brooksjeremy7 <92278656+brooksjeremy7@users.noreply.github.com> Date: Tue, 24 Jun 2025 12:29:11 -0700 Subject: [PATCH 2/2] fix: updated test to address extra precision in calculation --- tests/conditionalVault/unit/redeemTokens.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/conditionalVault/unit/redeemTokens.test.ts b/tests/conditionalVault/unit/redeemTokens.test.ts index 2fbfea43f..558d2dfa9 100644 --- a/tests/conditionalVault/unit/redeemTokens.test.ts +++ b/tests/conditionalVault/unit/redeemTokens.test.ts @@ -183,8 +183,7 @@ export default function suite() { ).then((acc) => acc.amount); assert.isTrue(balanceAfter > balanceBefore); - assert.isTrue(balanceAfter - balanceBefore < 1000); //dont need both these checks lol but just in case - assert.isTrue(balanceAfter - balanceBefore == 999); + assert.isTrue(balanceAfter - balanceBefore == 1000); // console.log('balanceAfter', balanceAfter);