feat(polygon_issues): Enhance gas price handling in EVM Chains

This change:
- Updates gas price calculation to account for minimum priority fee in Polygon
- Adjusts gas price handling to use maxFeePerGas when gasPrice is not provided.
- Fixes issue with send all for Polygon
This commit is contained in:
Blazebrain 2025-06-20 19:03:56 +01:00
parent 4589eb8149
commit b2bdd7166f
3 changed files with 56 additions and 14 deletions

View file

@ -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(

View file

@ -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<PendingTransaction> createApprovalTransaction(
BigInt amount,
String spender,
CryptoCurrency token,
EVMChainTransactionPriority priority) async {
Future<PendingTransaction> 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,
);
}

View file

@ -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,
);