Token delete bug fix (#2889)
What changed, and why it matters
This commit fixes a bug where deleting a custom token in the Solana or Tron wallet could fail or behave incorrectly. The old code tried to delete the token object directly, which could throw an error if the storage box wasn't open. The new code checks that the storage box is open and deletes the token by its unique address instead. There is also a minor formatting-only change in the Tron wallet's transaction code with no functional effect.
Treat as a routine bug-fix patch. Review whether closed-box states can be reached during normal use and consider adding tests for token deletion with closed storage boxes. No urgent security response is indicated by the diff alone.
Security signals we found
Deletion operation previously called on object without verifying storage state
Fix adds guard check before persistent storage delete
Potential runtime exception / data inconsistency during token deletion mitigated
Evidence from the diff
The patch changes deleteSPLToken and deleteTronToken to verify splTokensBox.isOpen / tronTokensBox.isOpen before calling box.delete(token.mintAddress) / box.delete(token.contractAddress), replacing direct await token.delete() calls. This prevents runtime errors during token deletion when the Hive box is closed and avoids potential mismatch between the in-memory token object and the persisted key. The Tron transaction-building code was reformatted (indentation and removed blank line) but its logic is unchanged.
Changed components
cw_solana/lib/solana_wallet.dartcw_tron/lib/tron_wallet.dartInspect captured patch +8 / −5
diff --git a/cw_solana/lib/solana_wallet.dart b/cw_solana/lib/solana_wallet.dart
index dba04a9d..e9d89d0f 100644
--- a/cw_solana/lib/solana_wallet.dart
+++ b/cw_solana/lib/solana_wallet.dart
@@ -645,7 +645,9 @@ abstract class SolanaWalletBase
}
Future<void> deleteSPLToken(SPLToken token) async {
- await token.delete();
+ if (splTokensBox.isOpen) {
+ await splTokensBox.delete(token.mintAddress);
+ }
balance.remove(token);
await _removeTokenTransactionsInHistory(token);
diff --git a/cw_tron/lib/tron_wallet.dart b/cw_tron/lib/tron_wallet.dart
index 393c8ff9..c8d9fb92 100644
--- a/cw_tron/lib/tron_wallet.dart
+++ b/cw_tron/lib/tron_wallet.dart
@@ -313,13 +313,12 @@ abstract class TronWalletBase
final hasMultiDestination = outputs.length > 1;
final transactionCurrency = balance.keys.firstWhere(
- (currency) =>
- currency.title == tronCredentials.currency.title &&
+ (currency) =>
+ currency.title == tronCredentials.currency.title &&
currency.tag == tronCredentials.currency.tag,
orElse: () => throw Exception(
'Currency ${tronCredentials.currency.title} ${tronCredentials.currency.tag} is not accessible in the wallet, try to enable it first.'));
-
final walletBalanceForCurrency = balance[transactionCurrency]!.balance;
BigInt totalAmount = BigInt.zero;
@@ -590,7 +589,9 @@ abstract class TronWalletBase
}
Future<void> deleteTronToken(TronToken token) async {
- await token.delete();
+ if (tronTokensBox.isOpen) {
+ await tronTokensBox.delete(token.contractAddress);
+ }
balance.remove(token);
await _removeTokenTransactionsInHistory(token);
Why this scored 27/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.