Fix transaction amount conversions

This commit is contained in:
OmarHatem 2023-07-22 05:59:38 +03:00
parent 87d414a34c
commit 5c2bd930b0
5 changed files with 29 additions and 27 deletions

View file

@ -97,6 +97,7 @@ class EthereumClient {
required int gas,
required EthereumTransactionPriority priority,
required CryptoCurrency currency,
required int exponent,
String? contractAddress,
}) async {
assert(currency == CryptoCurrency.eth || contractAddress != null);
@ -115,7 +116,7 @@ class EthereumClient {
final signedTransaction = await _client!.signTransaction(privateKey, transaction);
final estimatedGas;
final BigInt estimatedGas;
final Function _sendTransaction;
if (_isEthereum) {
@ -129,14 +130,10 @@ class EthereumClient {
address: EthereumAddress.fromHex(contractAddress!),
);
final originalAmount = BigInt.parse(amount) / BigInt.from(pow(10, 18));
final int exponent = (await erc20.decimals()).toInt();
final _amount = BigInt.from(originalAmount * pow(10, exponent));
_sendTransaction = () async {
await erc20.transfer(
EthereumAddress.fromHex(toAddress),
_amount,
BigInt.parse(amount),
credentials: privateKey,
);
};
@ -147,6 +144,7 @@ class EthereumClient {
amount: amount,
fee: estimatedGas * price.getInWei,
sendTransaction: _sendTransaction,
exponent: exponent,
);
}

View file

@ -1,8 +1,10 @@
import 'package:cw_core/crypto_currency.dart';
class EthereumTransactionCreationException implements Exception {
final String exceptionMessage;
EthereumTransactionCreationException(
{this.exceptionMessage = 'Wrong balance. Not enough Ether on your balance.'});
EthereumTransactionCreationException(CryptoCurrency currency) :
this.exceptionMessage = 'Wrong balance. Not enough ${currency.title} on your balance.';
@override
String toString() => exceptionMessage;

View file

@ -1,5 +1,3 @@
import 'dart:math';
import 'package:intl/intl.dart';
const ethereumAmountLength = 12;
@ -17,10 +15,9 @@ class EthereumFormatter {
}
}
static int parseEthereumBigIntAmount(BigInt amount) {
static double parseEthereumAmountToDouble(int amount) {
try {
double result = amount / BigInt.from(pow(10, 18 - ethereumAmountLength));
return result.toInt();
return amount / ethereumAmountDivider;
} catch (_) {
return 0;
}

View file

@ -147,30 +147,33 @@ abstract class EthereumWalletBase
final hasMultiDestination = outputs.length > 1;
final _erc20Balance = balance[_credentials.currency]!;
BigInt totalAmount = BigInt.zero;
BigInt amountToEthereumMultiplier = BigInt.from(pow(10, 18 - ethereumAmountLength));
int exponent =
_credentials.currency is Erc20Token ? (_credentials.currency as Erc20Token).decimal : 18;
BigInt amountToEthereumMultiplier = BigInt.from(pow(10, exponent));
if (hasMultiDestination) {
if (outputs.any((item) => item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) {
throw EthereumTransactionCreationException();
throw EthereumTransactionCreationException(_credentials.currency);
}
totalAmount =
BigInt.from(outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0))) *
amountToEthereumMultiplier;
final totalOriginalAmount = EthereumFormatter.parseEthereumAmountToDouble(
outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0)));
totalAmount = BigInt.from(totalOriginalAmount) * amountToEthereumMultiplier;
if (_erc20Balance.balance < totalAmount) {
throw EthereumTransactionCreationException();
throw EthereumTransactionCreationException(_credentials.currency);
}
} else {
final output = outputs.first;
final BigInt allAmount = _erc20Balance.balance - BigInt.from(feeRate(_credentials.priority!));
final totalOriginalAmount =
EthereumFormatter.parseEthereumAmountToDouble(output.formattedCryptoAmount ?? 0);
totalAmount = output.sendAll
? allAmount
: BigInt.from(output.formattedCryptoAmount ?? 0) * amountToEthereumMultiplier;
: BigInt.from(totalOriginalAmount) * amountToEthereumMultiplier;
if ((output.sendAll && _erc20Balance.balance < totalAmount) ||
(!output.sendAll && _erc20Balance.balance <= BigInt.zero)) {
throw EthereumTransactionCreationException();
if (_erc20Balance.balance < totalAmount) {
throw EthereumTransactionCreationException(_credentials.currency);
}
}
@ -181,6 +184,7 @@ abstract class EthereumWalletBase
gas: _priorityFees[_credentials.priority!.raw],
priority: _credentials.priority!,
currency: _credentials.currency,
exponent: exponent,
contractAddress: _credentials.currency is Erc20Token
? (_credentials.currency as Erc20Token).contractAddress
: null,

View file

@ -1,31 +1,32 @@
import 'dart:math';
import 'dart:typed_data';
import 'package:cw_core/pending_transaction.dart';
import 'package:web3dart/crypto.dart';
import 'package:web3dart/web3dart.dart';
class PendingEthereumTransaction with PendingTransaction {
final Function sendTransaction;
final Uint8List signedTransaction;
final BigInt fee;
final String amount;
final int exponent;
PendingEthereumTransaction({
required this.sendTransaction,
required this.signedTransaction,
required this.fee,
required this.amount,
required this.exponent,
});
@override
String get amountFormatted =>
EtherAmount.inWei(BigInt.parse(amount)).getValueInUnit(EtherUnit.ether).toString();
String get amountFormatted => (BigInt.parse(amount) / BigInt.from(pow(10, exponent))).toString();
@override
Future<void> commit() async => await sendTransaction();
@override
String get feeFormatted => EtherAmount.inWei(fee).getValueInUnit(EtherUnit.ether).toString();
String get feeFormatted => (fee / BigInt.from(pow(10, 18))).toString();
@override
String get hex => bytesToHex(signedTransaction, include0x: true);