fix(solana): fix Solana token tx parsing to handle plain "transfer" type
What changed, and why it matters
This commit fixes how Stack Wallet reads Solana token transactions. Previously, the wallet only recognized a specific detailed transfer format called 'transferChecked'. Now it also accepts the simpler 'transfer' format. Without this fix, some legitimate token transactions may have been missed or misrecorded, which could lead to incorrect balances or transaction history.
Review whether the unpatched behavior could cause user-visible accounting errors, and consider whether additional validation is needed for parsed.info.amount to prevent malformed transactions from affecting wallet state. No immediate exploit mitigation appears necessary.
Security signals we found
Transaction parsing logic change for token transfers
Potential balance/transaction history mismatch if unpatched
No explicit security framing in commit message
Evidence from the diff
The patch updates SolanaTokenWallet transaction parsing to handle both ‘transferChecked’ and plain ‘transfer’ SPL token instruction types. For ‘transferChecked’, the amount is read from parsed.info.tokenAmount.amount; for plain ‘transfer’, it is read from parsed.info.amount. The change is localized to a single Dart file and appears to be a correctness fix for transaction decoding.
Changed components
lib/wallets/wallet/impl/sub_wallets/solana_token_wallet.dartInspect captured patch +13 / −4
diff --git a/lib/wallets/wallet/impl/sub_wallets/solana_token_wallet.dart b/lib/wallets/wallet/impl/sub_wallets/solana_token_wallet.dart
index a311e05..5fb99a1 100644
--- a/lib/wallets/wallet/impl/sub_wallets/solana_token_wallet.dart
+++ b/lib/wallets/wallet/impl/sub_wallets/solana_token_wallet.dart
@@ -510,7 +510,8 @@ class SolanaTokenWallet extends Wallet {
(e) =>
e.containsKey("parsed") &&
e["program"] == "spl-token" &&
- e["parsed"]["type"] == "transferChecked",
+ (e["parsed"]["type"] == "transferChecked" ||
+ e["parsed"]["type"] == "transfer"),
);
if (splTransfers.length != 1) {
@@ -522,9 +523,17 @@ class SolanaTokenWallet extends Wallet {
continue;
}
final transfer = splTransfers.first;
- final lamports = BigInt.parse(
- transfer["parsed"]["info"]["tokenAmount"]["amount"].toString(),
- );
+ final transferType = transfer["parsed"]["type"] as String;
+ final BigInt lamports;
+ if (transferType == "transferChecked") {
+ lamports = BigInt.parse(
+ transfer["parsed"]["info"]["tokenAmount"]["amount"].toString(),
+ );
+ } else {
+ lamports = BigInt.parse(
+ transfer["parsed"]["info"]["amount"].toString(),
+ );
+ }
final senderAddress = transfer["parsed"]["info"]["source"] as String;
final receiverAddress =
transfer["parsed"]["info"]["destination"] as String;
Why this scored 36/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.