From cb56c1423106774ce4e2cc7ff02cd4dc588b3ac7 Mon Sep 17 00:00:00 2001 From: Peolite1 Date: Wed, 30 Sep 2026 04:47:52 +0100 Subject: [PATCH] Fix init option storage mismatch and add tests Closes #1104 --- contracts/vault/src/lib.rs | 19 +++++++++---- contracts/vault/src/test_init_hardening.rs | 31 ++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/contracts/vault/src/lib.rs b/contracts/vault/src/lib.rs index f5f1a483..0d235b01 100644 --- a/contracts/vault/src/lib.rs +++ b/contracts/vault/src/lib.rs @@ -280,6 +280,11 @@ impl CalloraVault { return Err(VaultError::MinDepositExceedsMaxDeduct); } + let initial_balance_val = initial_balance.unwrap_or(0); + if initial_balance_val < 0 { + return Err(VaultError::InitialBalanceNegative); + } + env.storage().instance().set(&DataKey::Owner, &owner); // The admin role defaults to the owner at initialization so the // timelocked lifecycle actions (pause / upgrade / sweep) and @@ -291,10 +296,14 @@ impl CalloraVault { .set(&DataKey::UsdcToken, &usdc_token); env.storage() .instance() - .set(&DataKey::Balance, &initial_balance); - env.storage() - .instance() - .set(&DataKey::AuthorizedCaller, &authorized_caller); + .set(&DataKey::Balance, &initial_balance_val); + + if let Some(ac) = authorized_caller { + env.storage() + .instance() + .set(&DataKey::AuthorizedCaller, &ac); + } + env.storage() .instance() .set(&DataKey::MinDeposit, &min_dep_val); @@ -312,7 +321,7 @@ impl CalloraVault { env.storage().instance().set(&DataKey::Paused, &false); env.events() - .publish((events::event_init(&env), events::event_version_v1(&env), owner.clone()), initial_balance); + .publish((events::event_init(&env), events::event_version_v1(&env), owner.clone()), initial_balance_val); Ok(()) } diff --git a/contracts/vault/src/test_init_hardening.rs b/contracts/vault/src/test_init_hardening.rs index ca0ec2fd..99cb9ba5 100644 --- a/contracts/vault/src/test_init_hardening.rs +++ b/contracts/vault/src/test_init_hardening.rs @@ -393,3 +393,34 @@ fn init_default_min_deposit_is_one() { ); assert_eq!(meta.min_deposit, DEFAULT_MIN_DEPOSIT); } + +#[test] +fn init_none_initial_balance_allows_deposit_and_deduct() { + let env = Env::default(); + env.mock_all_auths(); + let owner = Address::generate(&env); + let (_, client) = create_vault(&env); + let (usdc, _, usdc_admin) = create_usdc(&env, &owner); + let settlement = Address::generate(&env); + + client.init( + &owner, + &usdc, + &None, + &Some(owner.clone()), + &Some(1), + &None, + &Some(1000), + &Some(settlement), + ); + + usdc_admin.mint(&owner, &100); + + // Deposit 50 + client.deposit(&owner, &50); + assert_eq!(client.balance(), 50); + + // Deduct 20 + client.deduct(&owner, &20, &123); + assert_eq!(client.balance(), 30); +}