From 17582ce611090b51b692a55d6220edb4fbbdf802 Mon Sep 17 00:00:00 2001 From: jrooks7 Date: Wed, 25 Jun 2025 14:06:47 -0700 Subject: [PATCH 1/3] fix: added question resolution validation to three instructions --- .../src/instructions/initialize_conditional_vault.rs | 5 +++++ programs/conditional_vault/src/instructions/merge_tokens.rs | 5 +++++ programs/conditional_vault/src/instructions/split_tokens.rs | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/programs/conditional_vault/src/instructions/initialize_conditional_vault.rs b/programs/conditional_vault/src/instructions/initialize_conditional_vault.rs index 526ed0b6b..d0d2053de 100644 --- a/programs/conditional_vault/src/instructions/initialize_conditional_vault.rs +++ b/programs/conditional_vault/src/instructions/initialize_conditional_vault.rs @@ -34,6 +34,11 @@ pub struct InitializeConditionalVault<'info> { impl<'info, 'c: 'info> InitializeConditionalVault<'info> { pub fn handle(ctx: Context<'_, '_, 'c, 'info, Self>) -> Result<()> { + require!( + !ctx.accounts.question.is_resolved(), + VaultError::QuestionAlreadyResolved + ); + let vault = &mut ctx.accounts.vault; let decimals = ctx.accounts.underlying_token_mint.decimals; diff --git a/programs/conditional_vault/src/instructions/merge_tokens.rs b/programs/conditional_vault/src/instructions/merge_tokens.rs index eaa4cf1f8..bd3d5bb33 100644 --- a/programs/conditional_vault/src/instructions/merge_tokens.rs +++ b/programs/conditional_vault/src/instructions/merge_tokens.rs @@ -2,6 +2,11 @@ use super::*; impl<'info, 'c: 'info> InteractWithVault<'info> { pub fn handle_merge_tokens(ctx: Context<'_, '_, 'c, 'info, Self>, amount: u64) -> Result<()> { + require!( + !ctx.accounts.question.is_resolved(), + VaultError::QuestionAlreadyResolved + ); + let accs = &ctx.accounts; let (mut conditional_token_mints, mut user_conditional_token_accounts) = diff --git a/programs/conditional_vault/src/instructions/split_tokens.rs b/programs/conditional_vault/src/instructions/split_tokens.rs index 8ee776fc8..807002693 100644 --- a/programs/conditional_vault/src/instructions/split_tokens.rs +++ b/programs/conditional_vault/src/instructions/split_tokens.rs @@ -2,6 +2,11 @@ use super::*; impl<'info, 'c: 'info> InteractWithVault<'info> { pub fn handle_split_tokens(ctx: Context<'_, '_, 'c, 'info, Self>, amount: u64) -> Result<()> { + require!( + !ctx.accounts.question.is_resolved(), + VaultError::QuestionAlreadyResolved + ); + let accs = &ctx.accounts; let (mut conditional_token_mints, mut user_conditional_token_accounts) = From d1aad47d50bb74ffbb8ace6a343cbcad2eeee5f3 Mon Sep 17 00:00:00 2001 From: jrooks7 Date: Wed, 25 Jun 2025 14:28:08 -0700 Subject: [PATCH 2/3] fix: removed validation from merge and split tokens while adding a test to initialize conditional vault --- .../src/instructions/merge_tokens.rs | 4 -- .../src/instructions/split_tokens.rs | 4 -- .../unit/initializeConditionalVault.test.ts | 45 +++++++++++++++---- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/programs/conditional_vault/src/instructions/merge_tokens.rs b/programs/conditional_vault/src/instructions/merge_tokens.rs index bd3d5bb33..aed1d2bde 100644 --- a/programs/conditional_vault/src/instructions/merge_tokens.rs +++ b/programs/conditional_vault/src/instructions/merge_tokens.rs @@ -2,10 +2,6 @@ use super::*; impl<'info, 'c: 'info> InteractWithVault<'info> { pub fn handle_merge_tokens(ctx: Context<'_, '_, 'c, 'info, Self>, amount: u64) -> Result<()> { - require!( - !ctx.accounts.question.is_resolved(), - VaultError::QuestionAlreadyResolved - ); let accs = &ctx.accounts; diff --git a/programs/conditional_vault/src/instructions/split_tokens.rs b/programs/conditional_vault/src/instructions/split_tokens.rs index 807002693..f81576559 100644 --- a/programs/conditional_vault/src/instructions/split_tokens.rs +++ b/programs/conditional_vault/src/instructions/split_tokens.rs @@ -2,10 +2,6 @@ use super::*; impl<'info, 'c: 'info> InteractWithVault<'info> { pub fn handle_split_tokens(ctx: Context<'_, '_, 'c, 'info, Self>, amount: u64) -> Result<()> { - require!( - !ctx.accounts.question.is_resolved(), - VaultError::QuestionAlreadyResolved - ); let accs = &ctx.accounts; diff --git a/tests/conditionalVault/unit/initializeConditionalVault.test.ts b/tests/conditionalVault/unit/initializeConditionalVault.test.ts index bc45102e2..7c9ac1531 100644 --- a/tests/conditionalVault/unit/initializeConditionalVault.test.ts +++ b/tests/conditionalVault/unit/initializeConditionalVault.test.ts @@ -9,6 +9,7 @@ import { assert } from "chai"; import { createMint, getMint } from "spl-token-bankrun"; import * as anchor from "@coral-xyz/anchor"; import * as token from "@solana/spl-token"; +import { expectError } from "../../utils.js"; export default function suite() { let vaultClient: ConditionalVaultClient; @@ -33,19 +34,15 @@ export default function suite() { testCases.forEach(({ name, idArray, outcomes }) => { describe(name, function () { - let question: PublicKey; - let oracle: Keypair = Keypair.generate(); - - beforeEach(async function () { + it("initializes vaults correctly", async function () { + let oracle = Keypair.generate(); let questionId = sha256(new Uint8Array(idArray)); - question = await vaultClient.initializeQuestion( + let question = await vaultClient.initializeQuestion( questionId, oracle.publicKey, outcomes ); - }); - it("initializes vaults correctly", async function () { await vaultClient .initializeVaultIx(question, underlyingTokenMint, outcomes) .rpc(); @@ -89,6 +86,38 @@ export default function suite() { assert.isNull(storedMint.freezeAuthority); } }); + + it("doesn't allow initializing vault for resolved question", async function () { + let oracle = Keypair.generate(); + let questionId = sha256(new Uint8Array(idArray)); + let question = await vaultClient.initializeQuestion( + questionId, + oracle.publicKey, + outcomes + ); + + await vaultClient + .resolveQuestionIx(question, oracle, Array(outcomes).fill(1)) + .signers([oracle]) + .rpc(); + + const resolvedQuestion = await vaultClient.fetchQuestion(question); + assert.notEqual( + resolvedQuestion.payoutDenominator.toString(), + "0", + "Question should be resolved" + ); + + const callbacks = expectError( + "QuestionAlreadyResolved", + "Vault initialized despite question being resolved" + ); + + await vaultClient + .initializeVaultIx(question, underlyingTokenMint, outcomes) + .rpc() + .then(callbacks[0], callbacks[1]); + }); }); }); -} +} \ No newline at end of file From 803b5b1f2e929d79ed5062f560365a5f3ac741f7 Mon Sep 17 00:00:00 2001 From: jrooks7 Date: Wed, 25 Jun 2025 14:28:48 -0700 Subject: [PATCH 3/3] fix: removal of empty spaces --- programs/conditional_vault/src/instructions/merge_tokens.rs | 1 - programs/conditional_vault/src/instructions/split_tokens.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/programs/conditional_vault/src/instructions/merge_tokens.rs b/programs/conditional_vault/src/instructions/merge_tokens.rs index aed1d2bde..eaa4cf1f8 100644 --- a/programs/conditional_vault/src/instructions/merge_tokens.rs +++ b/programs/conditional_vault/src/instructions/merge_tokens.rs @@ -2,7 +2,6 @@ use super::*; impl<'info, 'c: 'info> InteractWithVault<'info> { pub fn handle_merge_tokens(ctx: Context<'_, '_, 'c, 'info, Self>, amount: u64) -> Result<()> { - let accs = &ctx.accounts; let (mut conditional_token_mints, mut user_conditional_token_accounts) = diff --git a/programs/conditional_vault/src/instructions/split_tokens.rs b/programs/conditional_vault/src/instructions/split_tokens.rs index f81576559..8ee776fc8 100644 --- a/programs/conditional_vault/src/instructions/split_tokens.rs +++ b/programs/conditional_vault/src/instructions/split_tokens.rs @@ -2,7 +2,6 @@ use super::*; impl<'info, 'c: 'info> InteractWithVault<'info> { pub fn handle_split_tokens(ctx: Context<'_, '_, 'c, 'info, Self>, amount: u64) -> Result<()> { - let accs = &ctx.accounts; let (mut conditional_token_mints, mut user_conditional_token_accounts) =