Context
GlobeWallet::add_asset vs. GlobeWallet::remove_asset, contracts/globe-wallet/src/lib.rs. Since issue #29, add_asset treats asset codes as equal case-insensitively for duplicate detection. remove_asset was never updated to match.
Problem
// add_asset's duplicate check:
if Self::codes_match_case_insensitive(&assets.get(i).unwrap().code, &asset.code) {
return Err(WalletError::AssetAlreadyAdded);
}
// remove_asset's lookup:
if a.code == asset_code { // exact match only
found = true;
} else {
new_assets.push_back(a);
}
The registry treats "USDC" and "usdc" as the same asset for the purpose of preventing a second registration, but as different assets for the purpose of removal.
Reproduction steps
#[test]
fn test_remove_asset_case_mismatch_fails_to_find_registered_asset() {
let (env, _cid, admin, client) = setup();
let user = Address::generate(&env);
client.add_asset(&user, &usdc(&env)); // registers "USDC"
// A client that passes through user input verbatim (e.g. a lowercase
// ticker typed into a search/filter box before calling remove) can't
// remove the asset it just displayed as present.
let result = client.try_remove_asset(&user, &String::from_str(&env, "usdc"));
assert_eq!(result, Err(Ok(WalletError::AssetNotFound))); // asset IS registered, just under different casing
assert_eq!(client.get_assets(&user).len(), 1); // still there, unremoved
}
Impact
Lower severity than the other issues in this batch — no fund loss — but a real, confusing correctness bug: a user (or an integration built against get_assets's returned casing vs. whatever casing a different code path happens to use) can be unable to remove an asset they can clearly see is registered, with an error (AssetNotFound) that gives no hint the real problem is casing rather than the asset genuinely being absent.
Suggested fix
Use codes_match_case_insensitive in remove_asset's lookup, the same way add_asset already does for its duplicate check — one canonicalization rule for asset-code identity, applied consistently everywhere that identity is compared.
Definition of done
Context
GlobeWallet::add_assetvs.GlobeWallet::remove_asset,contracts/globe-wallet/src/lib.rs. Since issue #29,add_assettreats asset codes as equal case-insensitively for duplicate detection.remove_assetwas never updated to match.Problem
The registry treats
"USDC"and"usdc"as the same asset for the purpose of preventing a second registration, but as different assets for the purpose of removal.Reproduction steps
Impact
Lower severity than the other issues in this batch — no fund loss — but a real, confusing correctness bug: a user (or an integration built against
get_assets's returned casing vs. whatever casing a different code path happens to use) can be unable to remove an asset they can clearly see is registered, with an error (AssetNotFound) that gives no hint the real problem is casing rather than the asset genuinely being absent.Suggested fix
Use
codes_match_case_insensitiveinremove_asset's lookup, the same wayadd_assetalready does for its duplicate check — one canonicalization rule for asset-code identity, applied consistently everywhere that identity is compared.Definition of done
remove_assetuses case-insensitive matching to find the asset to remove"USDC"can be removed by passing"usdc"(or any case variant)remove_assetstill correctly returnsAssetNotFoundfor a code that genuinely isn't registered under any casingcargo test --workspaceoutput pasted