mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
Label existing scam tokens (#2164)
* label existing scam tokens because users can get scammed twice ¯\_(ツ)_/¯ * minor ui fix [skip ci]
This commit is contained in:
parent
9ac784db5c
commit
88ebba9236
5 changed files with 89 additions and 53 deletions
|
@ -17,11 +17,11 @@ class Erc20Token extends CryptoCurrency with HiveObjectMixin {
|
||||||
@HiveField(4, defaultValue: true)
|
@HiveField(4, defaultValue: true)
|
||||||
bool _enabled;
|
bool _enabled;
|
||||||
@HiveField(5)
|
@HiveField(5)
|
||||||
final String? iconPath;
|
String? iconPath;
|
||||||
@HiveField(6)
|
@HiveField(6)
|
||||||
final String? tag;
|
final String? tag;
|
||||||
@HiveField(7, defaultValue: false)
|
@HiveField(7, defaultValue: false)
|
||||||
final bool isPotentialScam;
|
bool isPotentialScam;
|
||||||
|
|
||||||
bool get enabled => _enabled;
|
bool get enabled => _enabled;
|
||||||
|
|
||||||
|
|
|
@ -76,9 +76,13 @@ class EthereumWallet extends EVMChainWallet {
|
||||||
await erc20TokensBox.deleteFromDisk();
|
await erc20TokensBox.deleteFromDisk();
|
||||||
|
|
||||||
// Add all the previous tokens with configs to the new box
|
// Add all the previous tokens with configs to the new box
|
||||||
evmChainErc20TokensBox.addAll(allValues);
|
await evmChainErc20TokensBox.addAll(allValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get getDefaultTokenContractAddresses =>
|
||||||
|
DefaultEthereumErc20Tokens().initialErc20Tokens.map((e) => e.contractAddress).toList();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
EVMChainTransactionInfo getTransactionInfo(
|
EVMChainTransactionInfo getTransactionInfo(
|
||||||
EVMChainTransactionModel transactionModel, String address) {
|
EVMChainTransactionModel transactionModel, String address) {
|
||||||
|
|
|
@ -144,6 +144,8 @@ abstract class EVMChainWalletBase
|
||||||
// required WalletInfo walletInfo,
|
// required WalletInfo walletInfo,
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
List<String> get getDefaultTokenContractAddresses;
|
||||||
|
|
||||||
Future<void> initErc20TokensBox();
|
Future<void> initErc20TokensBox();
|
||||||
|
|
||||||
String getTransactionHistoryFileName();
|
String getTransactionHistoryFileName();
|
||||||
|
@ -171,6 +173,9 @@ abstract class EVMChainWalletBase
|
||||||
await walletAddresses.init();
|
await walletAddresses.init();
|
||||||
await transactionHistory.init();
|
await transactionHistory.init();
|
||||||
|
|
||||||
|
// check for Already existing scam tokens, cuz users can get scammed twice ¯\_(ツ)_/¯
|
||||||
|
await _checkForExistingScamTokens();
|
||||||
|
|
||||||
if (walletInfo.isHardwareWallet) {
|
if (walletInfo.isHardwareWallet) {
|
||||||
_evmChainPrivateKey = EvmLedgerCredentials(walletInfo.address);
|
_evmChainPrivateKey = EvmLedgerCredentials(walletInfo.address);
|
||||||
walletAddresses.address = walletInfo.address;
|
walletAddresses.address = walletInfo.address;
|
||||||
|
@ -186,6 +191,31 @@ abstract class EVMChainWalletBase
|
||||||
await save();
|
await save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _checkForExistingScamTokens() async {
|
||||||
|
final baseCurrencySymbols = CryptoCurrency.all.map((e) => e.title.toUpperCase()).toList();
|
||||||
|
|
||||||
|
for (var token in erc20Currencies) {
|
||||||
|
bool isPotentialScam = false;
|
||||||
|
|
||||||
|
bool isWhitelisted =
|
||||||
|
getDefaultTokenContractAddresses.any((element) => element == token.contractAddress);
|
||||||
|
|
||||||
|
final tokenSymbol = token.title.toUpperCase();
|
||||||
|
|
||||||
|
// check if the token symbol is the same as any of the base currencies symbols (ETH, SOL, POL, TRX, etc):
|
||||||
|
// if it is, then it's probably a scam unless it's in the whitelist
|
||||||
|
if (baseCurrencySymbols.contains(tokenSymbol.trim().toUpperCase()) && !isWhitelisted) {
|
||||||
|
isPotentialScam = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPotentialScam) {
|
||||||
|
token.isPotentialScam = true;
|
||||||
|
token.iconPath = null;
|
||||||
|
await token.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
int calculateEstimatedFee(TransactionPriority priority, int? amount) {
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,10 @@ class PolygonWallet extends EVMChainWallet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<String> get getDefaultTokenContractAddresses =>
|
||||||
|
DefaultPolygonErc20Tokens().initialPolygonErc20Tokens.map((e) => e.contractAddress).toList();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> checkIfScanProviderIsEnabled() async {
|
Future<bool> checkIfScanProviderIsEnabled() async {
|
||||||
bool isPolygonScanEnabled = (await sharedPrefs.future).getBool("use_polygonscan") ?? true;
|
bool isPolygonScanEnabled = (await sharedPrefs.future).getBool("use_polygonscan") ?? true;
|
||||||
|
|
|
@ -397,7 +397,6 @@ class SendPage extends BasePage {
|
||||||
return LoadingPrimaryButton(
|
return LoadingPrimaryButton(
|
||||||
key: ValueKey('send_page_send_button_key'),
|
key: ValueKey('send_page_send_button_key'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
|
|
||||||
//Request dummy node to get the focus out of the text fields
|
//Request dummy node to get the focus out of the text fields
|
||||||
FocusScope.of(context).requestFocus(FocusNode());
|
FocusScope.of(context).requestFocus(FocusNode());
|
||||||
|
|
||||||
|
@ -507,7 +506,6 @@ class SendPage extends BasePage {
|
||||||
Navigator.of(loadingBottomSheetContext!).pop();
|
Navigator.of(loadingBottomSheetContext!).pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (state is FailureState) {
|
if (state is FailureState) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
showPopUp<void>(
|
showPopUp<void>(
|
||||||
|
@ -525,7 +523,6 @@ class SendPage extends BasePage {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state is IsExecutingState) {
|
if (state is IsExecutingState) {
|
||||||
|
|
||||||
// wait a bit to avoid showing the loading dialog if transaction is failed
|
// wait a bit to avoid showing the loading dialog if transaction is failed
|
||||||
await Future.delayed(const Duration(milliseconds: 300));
|
await Future.delayed(const Duration(milliseconds: 300));
|
||||||
final currentState = sendViewModel.state;
|
final currentState = sendViewModel.state;
|
||||||
|
@ -584,8 +581,6 @@ class SendPage extends BasePage {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (state is TransactionCommitted) {
|
if (state is TransactionCommitted) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
if (!context.mounted) {
|
if (!context.mounted) {
|
||||||
|
@ -594,7 +589,8 @@ class SendPage extends BasePage {
|
||||||
|
|
||||||
newContactAddress = newContactAddress ?? sendViewModel.newContactAddress();
|
newContactAddress = newContactAddress ?? sendViewModel.newContactAddress();
|
||||||
|
|
||||||
if (newContactAddress?.address != null && isRegularElectrumAddress(newContactAddress!.address)) {
|
if (newContactAddress?.address != null &&
|
||||||
|
isRegularElectrumAddress(newContactAddress!.address)) {
|
||||||
newContactAddress = null;
|
newContactAddress = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,25 +607,27 @@ class SendPage extends BasePage {
|
||||||
onCheckboxChanged: (value) => sendViewModel.setShowAddressBookPopup(!value),
|
onCheckboxChanged: (value) => sendViewModel.setShowAddressBookPopup(!value),
|
||||||
titleText: S.of(bottomSheetContext).transaction_sent,
|
titleText: S.of(bottomSheetContext).transaction_sent,
|
||||||
contentImage: 'assets/images/contact_icon.svg',
|
contentImage: 'assets/images/contact_icon.svg',
|
||||||
contentImageColor: Theme.of(context)
|
contentImageColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||||
.extension<CakeTextTheme>()!
|
|
||||||
.titleColor,
|
|
||||||
content: S.of(bottomSheetContext).add_contact_to_address_book,
|
content: S.of(bottomSheetContext).add_contact_to_address_book,
|
||||||
isTwoAction: true,
|
isTwoAction: true,
|
||||||
leftButtonText: 'No',
|
leftButtonText: 'No',
|
||||||
rightButtonText: 'Yes',
|
rightButtonText: 'Yes',
|
||||||
actionLeftButton: () {
|
actionLeftButton: () {
|
||||||
Navigator.of(bottomSheetContext).pop();
|
Navigator.of(bottomSheetContext).pop();
|
||||||
|
if (context.mounted) {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
|
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
|
||||||
|
}
|
||||||
RequestReviewHandler.requestReview();
|
RequestReviewHandler.requestReview();
|
||||||
newContactAddress = null;
|
newContactAddress = null;
|
||||||
},
|
},
|
||||||
actionRightButton: () {
|
actionRightButton: () {
|
||||||
Navigator.of(bottomSheetContext).pop();
|
Navigator.of(bottomSheetContext).pop();
|
||||||
RequestReviewHandler.requestReview();
|
RequestReviewHandler.requestReview();
|
||||||
Navigator.of(context)
|
if (context.mounted) {
|
||||||
.pushNamed(Routes.addressBookAddContact, arguments: newContactAddress);
|
Navigator.of(context).pushNamed(Routes.addressBookAddContact,
|
||||||
|
arguments: newContactAddress);
|
||||||
|
}
|
||||||
newContactAddress = null;
|
newContactAddress = null;
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -641,8 +639,10 @@ class SendPage extends BasePage {
|
||||||
actionButtonKey: ValueKey('send_page_sent_dialog_ok_button_key'),
|
actionButtonKey: ValueKey('send_page_sent_dialog_ok_button_key'),
|
||||||
actionButton: () {
|
actionButton: () {
|
||||||
Navigator.of(bottomSheetContext).pop();
|
Navigator.of(bottomSheetContext).pop();
|
||||||
|
if (context.mounted) {
|
||||||
Navigator.of(context)
|
Navigator.of(context)
|
||||||
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
|
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
|
||||||
|
}
|
||||||
RequestReviewHandler.requestReview();
|
RequestReviewHandler.requestReview();
|
||||||
newContactAddress = null;
|
newContactAddress = null;
|
||||||
},
|
},
|
||||||
|
@ -678,8 +678,7 @@ class SendPage extends BasePage {
|
||||||
currentTheme: currentTheme,
|
currentTheme: currentTheme,
|
||||||
titleText: S.of(bottomSheetContext).proceed_on_device,
|
titleText: S.of(bottomSheetContext).proceed_on_device,
|
||||||
contentImage: 'assets/images/hardware_wallet/ledger_nano_x.png',
|
contentImage: 'assets/images/hardware_wallet/ledger_nano_x.png',
|
||||||
contentImageColor:
|
contentImageColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||||
Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
|
||||||
content: S.of(bottomSheetContext).proceed_on_device_description,
|
content: S.of(bottomSheetContext).proceed_on_device_description,
|
||||||
isTwoAction: false,
|
isTwoAction: false,
|
||||||
actionButtonText: S.of(context).cancel,
|
actionButtonText: S.of(context).cancel,
|
||||||
|
@ -778,5 +777,4 @@ class SendPage extends BasePage {
|
||||||
|
|
||||||
return isValid;
|
return isValid;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue