diff --git a/cw_evm/lib/evm_chain_client.dart b/cw_evm/lib/evm_chain_client.dart index 5f383b5a3..1fecc9c1e 100644 --- a/cw_evm/lib/evm_chain_client.dart +++ b/cw_evm/lib/evm_chain_client.dart @@ -109,7 +109,6 @@ abstract class EVMChainClient { sender: senderAddress, to: toAddress, value: value, - // maxFeePerGas: maxFeePerGas, ); return estimatedGas.toInt(); @@ -165,6 +164,7 @@ abstract class EVMChainClient { required int exponent, String? contractAddress, String? data, + int? gasPrice, }) async { assert(currency == CryptoCurrency.eth || currency == CryptoCurrency.maticpoly || @@ -180,6 +180,7 @@ abstract class EVMChainClient { data: data != null ? hexToBytes(data) : null, maxGas: estimatedGasUnits, maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas), + gasPrice: gasPrice != null ? EtherAmount.fromInt(EtherUnit.wei, gasPrice) : null, ); Uint8List signedTransaction; @@ -224,6 +225,7 @@ abstract class EVMChainClient { required EVMChainTransactionPriority priority, required int exponent, required String contractAddress, + int? gasPrice, }) async { final Transaction transaction = createTransaction( @@ -233,6 +235,7 @@ abstract class EVMChainClient { amount: EtherAmount.zero(), maxGas: estimatedGasUnits, maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas), + gasPrice: gasPrice != null ? EtherAmount.fromInt(EtherUnit.wei, gasPrice) : null, ); final erc20 = ERC20( diff --git a/cw_evm/lib/evm_chain_wallet.dart b/cw_evm/lib/evm_chain_wallet.dart index 18f6e6ee5..1791258f5 100644 --- a/cw_evm/lib/evm_chain_wallet.dart +++ b/cw_evm/lib/evm_chain_wallet.dart @@ -263,31 +263,65 @@ abstract class EVMChainWalletBase final priorityFee = EtherAmount.fromInt(EtherUnit.gwei, priority.tip).getInWei.toInt(); int maxFeePerGas; + int adjustedGasPrice; + + bool isPolygon = _client.chainId == 137; + if (gasBaseFee != null) { // MaxFeePerGas with EIP1559; maxFeePerGas = gasBaseFee! + priorityFee; } else { // MaxFeePerGas with gasPrice - maxFeePerGas = gasPrice; + maxFeePerGas = gasPrice + priorityFee; + } + + adjustedGasPrice = maxFeePerGas; + + // Polygon has a minimum priority fee of 25 gwei + if (isPolygon) { + int minPriorityFee = 25; + int minPriorityFeeWei = + EtherAmount.fromInt(EtherUnit.gwei, minPriorityFee).getInWei.toInt(); + + // Calculate user selected priority-based additional fee on top of minimum + int additionalPriorityFee = 0; + switch (priority) { + case EVMChainTransactionPriority.slow: + // We use minimum priority fee only + additionalPriorityFee = 0; + break; + case EVMChainTransactionPriority.medium: + // We add 15 gwei on top of minimum + additionalPriorityFee = EtherAmount.fromInt(EtherUnit.gwei, 15).getInWei.toInt(); + break; + case EVMChainTransactionPriority.fast: + // We add 35 gwei on top of minimum + additionalPriorityFee = EtherAmount.fromInt(EtherUnit.gwei, 35).getInWei.toInt(); + break; + } + + int totalPriorityFee = minPriorityFeeWei + additionalPriorityFee; + adjustedGasPrice = gasPrice + totalPriorityFee; + maxFeePerGas = gasPrice + totalPriorityFee; } final estimatedGas = await _client.getEstimatedGasUnitsForTransaction( contractAddress: contractAddress, senderAddress: _evmChainPrivateKey.address, value: EtherAmount.fromBigInt(EtherUnit.wei, amount!), - gasPrice: EtherAmount.fromInt(EtherUnit.wei, gasPrice), + gasPrice: EtherAmount.fromInt(EtherUnit.wei, adjustedGasPrice), toAddress: EthereumAddress.fromHex(receivingAddressHex), maxFeePerGas: EtherAmount.fromInt(EtherUnit.wei, maxFeePerGas), data: data, ); - final totalGasFee = estimatedGas * maxFeePerGas; + final totalGasFee = estimatedGas * adjustedGasPrice; return GasParamsHandler( estimatedGasUnits: estimatedGas, estimatedGasFee: totalGasFee, maxFeePerGas: maxFeePerGas, - gasPrice: gasPrice, + gasPrice: adjustedGasPrice, ); } return GasParamsHandler.zero(); @@ -476,23 +510,20 @@ abstract class EVMChainWalletBase contractAddress: transactionCurrency is Erc20Token ? transactionCurrency.contractAddress : null, data: hexOpReturnMemo, + gasPrice: maxFeePerGasForTransaction, ); return pendingEVMChainTransaction; } - Future createApprovalTransaction( - BigInt amount, - String spender, - CryptoCurrency token, - EVMChainTransactionPriority priority) async { + Future createApprovalTransaction(BigInt amount, String spender, + CryptoCurrency token, EVMChainTransactionPriority priority) async { final CryptoCurrency transactionCurrency = balance.keys.firstWhere((element) => element.title == token.title); assert(transactionCurrency is Erc20Token); final data = _client.getEncodedDataForApprovalTransaction( - contractAddress: EthereumAddress.fromHex( - (transactionCurrency as Erc20Token).contractAddress), + contractAddress: EthereumAddress.fromHex((transactionCurrency as Erc20Token).contractAddress), value: EtherAmount.fromBigInt(EtherUnit.wei, amount), toAddress: EthereumAddress.fromHex(spender), ); @@ -515,6 +546,7 @@ abstract class EVMChainWalletBase estimatedGasUnits: gasFeesModel.estimatedGasUnits, exponent: transactionCurrency.decimal, contractAddress: transactionCurrency.contractAddress, + gasPrice: gasFeesModel.gasPrice, ); } diff --git a/cw_polygon/lib/default_polygon_erc20_tokens.dart b/cw_polygon/lib/default_polygon_erc20_tokens.dart index 2c739e8c5..208a63345 100644 --- a/cw_polygon/lib/default_polygon_erc20_tokens.dart +++ b/cw_polygon/lib/default_polygon_erc20_tokens.dart @@ -84,6 +84,6 @@ class DefaultPolygonErc20Tokens { .iconPath; } catch (_) {} - return Erc20Token.copyWith(token, iconPath, 'POLY'); + return Erc20Token.copyWith(token, iconPath, 'POL'); }).toList(); } diff --git a/cw_polygon/lib/polygon_client.dart b/cw_polygon/lib/polygon_client.dart index 5c344debe..62dcec50e 100644 --- a/cw_polygon/lib/polygon_client.dart +++ b/cw_polygon/lib/polygon_client.dart @@ -18,13 +18,20 @@ class PolygonClient extends EVMChainClient { EtherAmount? gasPrice, EtherAmount? maxFeePerGas, }) { + EtherAmount? finalGasPrice = gasPrice; + + if (gasPrice == null && maxFeePerGas != null) { + // If we have EIP-1559 parameters but no legacy gasPrice, then use maxFeePerGas as gasPrice + finalGasPrice = maxFeePerGas; + } + return Transaction( from: from, to: to, value: amount, - // data: data, + data: data, maxGas: maxGas, - // gasPrice: gasPrice, + gasPrice: finalGasPrice, // maxFeePerGas: maxFeePerGas, // maxPriorityFeePerGas: maxPriorityFeePerGas, ); diff --git a/cw_polygon/lib/polygon_wallet.dart b/cw_polygon/lib/polygon_wallet.dart index c1d36b9cb..991552068 100644 --- a/cw_polygon/lib/polygon_wallet.dart +++ b/cw_polygon/lib/polygon_wallet.dart @@ -45,7 +45,12 @@ class PolygonWallet extends EVMChainWallet { final initialErc20Tokens = DefaultPolygonErc20Tokens().initialPolygonErc20Tokens; for (final token in initialErc20Tokens) { - if (!evmChainErc20TokensBox.containsKey(token.contractAddress)) { + if (evmChainErc20TokensBox.containsKey(token.contractAddress)) { + final existingToken = evmChainErc20TokensBox.get(token.contractAddress); + if (existingToken?.tag != token.tag) { + evmChainErc20TokensBox.put(token.contractAddress, token); + } + } else { if (isMigration) token.enabled = false; evmChainErc20TokensBox.put(token.contractAddress, token); }