ensure eth wallet is fully synced/refreshed before first refresh of a token wallet hack
What changed, and why it matters
This commit changes how an Ethereum token wallet first refreshes its data. It adds a one-time workaround that forces the parent Ethereum wallet to fully sync before the token wallet refreshes for the first time. The developer explicitly labels this as an unverified and untested hack. The change also includes minor code formatting cleanups. There is no direct evidence in the commit that this fixes a security vulnerability; it appears aimed at preventing stale or incorrect balance/transaction state when a token wallet is first used.
Treat as a reliability/workaround change rather than a confirmed security fix. Review whether the first-refresh ordering issue could lead to incorrect balance or transaction display, and replace the hack flag with a robust synchronization dependency once verified. No urgent security patch action is indicated by the available evidence.
Security signals we found
Workaround/hack flag added to synchronization path
Potential race or stale-state issue between parent ETH wallet and token sub-wallet
No explicit security claim in commit message or diff
No input validation, cryptographic, or authorization changes
Evidence from the diff
The patch modifies EthTokenWallet.refresh() to call ethWallet.refresh() once before invoking super.refresh(). A boolean flag named _unverifiedAndUntestedHackFlagThatMightFixAnIssue guards this so it only happens on the first refresh. The stated intent is to ensure the base ETH wallet is fully synced/refreshed before the token wallet’s first refresh. The remainder of the diff is non-functional formatting changes (line wrapping). No security bug, exploit primitive, or vulnerability root cause is described in the commit message or diff.
Changed components
lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dartEthTokenWallet.refresh()ETH token sub-wallet synchronizationInspect captured patch +23 / −14
diff --git a/lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart b/lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart
index e45babf..d101552 100644
--- a/lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart
+++ b/lib/wallets/wallet/impl/sub_wallets/eth_token_wallet.dart
@@ -110,10 +110,9 @@ class EthTokenWallet extends Wallet {
inputs: List.unmodifiable(inputs),
outputs: List.unmodifiable(outputs),
version: -1,
- type:
- addressTo == myAddress
- ? TransactionType.sentToSelf
- : TransactionType.outgoing,
+ type: addressTo == myAddress
+ ? TransactionType.sentToSelf
+ : TransactionType.outgoing,
subType: TransactionSubType.ethToken,
otherData: jsonEncode(otherData),
);
@@ -131,6 +130,18 @@ class EthTokenWallet extends Wallet {
FilterOperation? get receivingAddressFilterOperation =>
ethWallet.receivingAddressFilterOperation;
+ bool _unverifiedAndUntestedHackFlagThatMightFixAnIssue = true;
+
+ @override
+ Future<void> refresh() async {
+ if (_unverifiedAndUntestedHackFlagThatMightFixAnIssue) {
+ await ethWallet.refresh();
+ _unverifiedAndUntestedHackFlagThatMightFixAnIssue = false;
+ }
+
+ return super.refresh();
+ }
+
@override
Future<void> init() async {
try {
@@ -217,11 +228,10 @@ class EthTokenWallet extends Wallet {
// double check balance after internalSharedPrepareSend call to ensure
// balance is up to date
- final info =
- await mainDB.isar.tokenWalletInfo
- .where()
- .walletIdTokenAddressEqualTo(walletId, tokenContract.address)
- .findFirst();
+ final info = await mainDB.isar.tokenWalletInfo
+ .where()
+ .walletIdTokenAddressEqualTo(walletId, tokenContract.address)
+ .findFirst();
final availableBalance =
info?.getCachedBalance().spendable ??
Amount.zeroWith(fractionDigits: tokenContract.decimals);
@@ -302,11 +312,10 @@ class EthTokenWallet extends Wallet {
@override
Future<void> updateBalance() async {
try {
- final info =
- await mainDB.isar.tokenWalletInfo
- .where()
- .walletIdTokenAddressEqualTo(walletId, tokenContract.address)
- .findFirst();
+ final info = await mainDB.isar.tokenWalletInfo
+ .where()
+ .walletIdTokenAddressEqualTo(walletId, tokenContract.address)
+ .findFirst();
final response = await EthereumAPI.getWalletTokenBalance(
address: (await getCurrentReceivingAddress())!.value,
contractAddress: tokenContract.address,
Why this scored 32/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.