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)
|
||||
bool _enabled;
|
||||
@HiveField(5)
|
||||
final String? iconPath;
|
||||
String? iconPath;
|
||||
@HiveField(6)
|
||||
final String? tag;
|
||||
@HiveField(7, defaultValue: false)
|
||||
final bool isPotentialScam;
|
||||
bool isPotentialScam;
|
||||
|
||||
bool get enabled => _enabled;
|
||||
|
||||
|
|
|
@ -76,9 +76,13 @@ class EthereumWallet extends EVMChainWallet {
|
|||
await erc20TokensBox.deleteFromDisk();
|
||||
|
||||
// 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
|
||||
EVMChainTransactionInfo getTransactionInfo(
|
||||
EVMChainTransactionModel transactionModel, String address) {
|
||||
|
|
|
@ -144,6 +144,8 @@ abstract class EVMChainWalletBase
|
|||
// required WalletInfo walletInfo,
|
||||
// });
|
||||
|
||||
List<String> get getDefaultTokenContractAddresses;
|
||||
|
||||
Future<void> initErc20TokensBox();
|
||||
|
||||
String getTransactionHistoryFileName();
|
||||
|
@ -171,6 +173,9 @@ abstract class EVMChainWalletBase
|
|||
await walletAddresses.init();
|
||||
await transactionHistory.init();
|
||||
|
||||
// check for Already existing scam tokens, cuz users can get scammed twice ¯\_(ツ)_/¯
|
||||
await _checkForExistingScamTokens();
|
||||
|
||||
if (walletInfo.isHardwareWallet) {
|
||||
_evmChainPrivateKey = EvmLedgerCredentials(walletInfo.address);
|
||||
walletAddresses.address = walletInfo.address;
|
||||
|
@ -186,6 +191,31 @@ abstract class EVMChainWalletBase
|
|||
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
|
||||
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
|
||||
Future<bool> checkIfScanProviderIsEnabled() async {
|
||||
bool isPolygonScanEnabled = (await sharedPrefs.future).getBool("use_polygonscan") ?? true;
|
||||
|
|
|
@ -98,7 +98,7 @@ class SendPage extends BasePage {
|
|||
return MergeSemantics(
|
||||
child: SizedBox(
|
||||
height: isMobileView ? 37 : 45,
|
||||
width: isMobileView ? 47: 45,
|
||||
width: isMobileView ? 47 : 45,
|
||||
child: ButtonTheme(
|
||||
minWidth: double.minPositive,
|
||||
child: Semantics(
|
||||
|
@ -397,7 +397,6 @@ class SendPage extends BasePage {
|
|||
return LoadingPrimaryButton(
|
||||
key: ValueKey('send_page_send_button_key'),
|
||||
onPressed: () async {
|
||||
|
||||
//Request dummy node to get the focus out of the text fields
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
|
||||
|
@ -507,7 +506,6 @@ class SendPage extends BasePage {
|
|||
Navigator.of(loadingBottomSheetContext!).pop();
|
||||
}
|
||||
|
||||
|
||||
if (state is FailureState) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
showPopUp<void>(
|
||||
|
@ -525,7 +523,6 @@ class SendPage extends BasePage {
|
|||
}
|
||||
|
||||
if (state is IsExecutingState) {
|
||||
|
||||
// wait a bit to avoid showing the loading dialog if transaction is failed
|
||||
await Future.delayed(const Duration(milliseconds: 300));
|
||||
final currentState = sendViewModel.state;
|
||||
|
@ -584,8 +581,6 @@ class SendPage extends BasePage {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (state is TransactionCommitted) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
if (!context.mounted) {
|
||||
|
@ -594,7 +589,8 @@ class SendPage extends BasePage {
|
|||
|
||||
newContactAddress = newContactAddress ?? sendViewModel.newContactAddress();
|
||||
|
||||
if (newContactAddress?.address != null && isRegularElectrumAddress(newContactAddress!.address)) {
|
||||
if (newContactAddress?.address != null &&
|
||||
isRegularElectrumAddress(newContactAddress!.address)) {
|
||||
newContactAddress = null;
|
||||
}
|
||||
|
||||
|
@ -611,25 +607,27 @@ class SendPage extends BasePage {
|
|||
onCheckboxChanged: (value) => sendViewModel.setShowAddressBookPopup(!value),
|
||||
titleText: S.of(bottomSheetContext).transaction_sent,
|
||||
contentImage: 'assets/images/contact_icon.svg',
|
||||
contentImageColor: Theme.of(context)
|
||||
.extension<CakeTextTheme>()!
|
||||
.titleColor,
|
||||
contentImageColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
content: S.of(bottomSheetContext).add_contact_to_address_book,
|
||||
isTwoAction: true,
|
||||
leftButtonText: 'No',
|
||||
rightButtonText: 'Yes',
|
||||
actionLeftButton: () {
|
||||
Navigator.of(bottomSheetContext).pop();
|
||||
if (context.mounted) {
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
|
||||
}
|
||||
RequestReviewHandler.requestReview();
|
||||
newContactAddress = null;
|
||||
},
|
||||
actionRightButton: () {
|
||||
Navigator.of(bottomSheetContext).pop();
|
||||
RequestReviewHandler.requestReview();
|
||||
Navigator.of(context)
|
||||
.pushNamed(Routes.addressBookAddContact, arguments: newContactAddress);
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).pushNamed(Routes.addressBookAddContact,
|
||||
arguments: newContactAddress);
|
||||
}
|
||||
newContactAddress = null;
|
||||
},
|
||||
)
|
||||
|
@ -641,8 +639,10 @@ class SendPage extends BasePage {
|
|||
actionButtonKey: ValueKey('send_page_sent_dialog_ok_button_key'),
|
||||
actionButton: () {
|
||||
Navigator.of(bottomSheetContext).pop();
|
||||
if (context.mounted) {
|
||||
Navigator.of(context)
|
||||
.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
|
||||
}
|
||||
RequestReviewHandler.requestReview();
|
||||
newContactAddress = null;
|
||||
},
|
||||
|
@ -678,8 +678,7 @@ class SendPage extends BasePage {
|
|||
currentTheme: currentTheme,
|
||||
titleText: S.of(bottomSheetContext).proceed_on_device,
|
||||
contentImage: 'assets/images/hardware_wallet/ledger_nano_x.png',
|
||||
contentImageColor:
|
||||
Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
contentImageColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
|
||||
content: S.of(bottomSheetContext).proceed_on_device_description,
|
||||
isTwoAction: false,
|
||||
actionButtonText: S.of(context).cancel,
|
||||
|
@ -778,5 +777,4 @@ class SendPage extends BasePage {
|
|||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue