From a8cf860811ae1a8409adc5593f3635f9ca537171 Mon Sep 17 00:00:00 2001 From: ZacLou Date: Wed, 2 Sep 2026 23:08:34 +0800 Subject: [PATCH] fix(globe-wallet): remove SpendLimit/DailySpent when removing asset Closes Orbit-Wal/contract#89. emove_asset previously left the per-asset SpendLimit and DailySpent entries in persistent storage, causing unbounded storage growth and surprising behavior when the asset was re-added later. Clean them up alongside the UserAssets entry, matching the cleanup already done by migrate_user_assets. Also adds tests proving the limit resets to 0 after removal, re-adding starts fresh, and other asset limits are untouched. --- contracts/globe-wallet/src/lib.rs | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/contracts/globe-wallet/src/lib.rs b/contracts/globe-wallet/src/lib.rs index ef047b8..97f2d7d 100644 --- a/contracts/globe-wallet/src/lib.rs +++ b/contracts/globe-wallet/src/lib.rs @@ -1133,6 +1133,14 @@ impl GlobeWallet { env.storage() .persistent() .set(&DataKey::UserAssets(user.clone()), &new_assets); + // Clean up the per-asset spend-limit state so re-adding the asset later + // starts fresh and persistent storage does not grow unbounded. + env.storage() + .persistent() + .remove(&DataKey::SpendLimit(user.clone(), asset_code.clone())); + env.storage() + .persistent() + .remove(&DataKey::DailySpent(user.clone(), asset_code.clone())); env.storage().persistent().extend_ttl( &DataKey::UserAssets(user.clone()), PERSISTENT_TTL_THRESHOLD, @@ -1775,6 +1783,38 @@ mod tests { assert_eq!(assets.get(0).unwrap().code, String::from_str(&env, "USDC")); } + #[test] + fn test_remove_asset_clears_spend_limit_and_daily_spent() { + let (env, _cid, _admin, client) = setup(); + let user = Address::generate(&env); + let code = String::from_str(&env, "USDC"); + client.add_asset(&user, &usdc(&env)); + client.set_spend_limit(&user, &code, &500_i128); + client.record_spend(&user, &code, &200_i128); + client.remove_asset(&user, &code); + assert_eq!(client.get_assets(&user).len(), 0); + // Spend limit should reset to default (0 = unlimited). + assert_eq!(client.get_spend_limit(&user, &code), 0); + // Re-adding the same asset should start with a fresh, unconfigured limit. + client.add_asset(&user, &usdc(&env)); + assert_eq!(client.get_spend_limit(&user, &code), 0); + } + + #[test] + fn test_remove_asset_keeps_other_asset_limits_intact() { + let (env, _cid, _admin, client) = setup(); + let user = Address::generate(&env); + let usdc_code = String::from_str(&env, "USDC"); + let xlm_code = String::from_str(&env, "XLM"); + client.add_asset(&user, &usdc(&env)); + client.add_asset(&user, &xlm(&env)); + client.set_spend_limit(&user, &usdc_code, &500_i128); + client.set_spend_limit(&user, &xlm_code, &1_000_i128); + client.remove_asset(&user, &usdc_code); + assert_eq!(client.get_spend_limit(&user, &usdc_code), 0); + assert_eq!(client.get_spend_limit(&user, &xlm_code), 1_000); + } + #[test] fn test_remove_nonexistent_asset_fails() { let (env, _cid, _admin, client) = setup();