mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-27 13:06:07 +00:00
Fix transaction amount conversions
This commit is contained in:
parent
87d414a34c
commit
5c2bd930b0
5 changed files with 29 additions and 27 deletions
|
@ -97,6 +97,7 @@ class EthereumClient {
|
||||||
required int gas,
|
required int gas,
|
||||||
required EthereumTransactionPriority priority,
|
required EthereumTransactionPriority priority,
|
||||||
required CryptoCurrency currency,
|
required CryptoCurrency currency,
|
||||||
|
required int exponent,
|
||||||
String? contractAddress,
|
String? contractAddress,
|
||||||
}) async {
|
}) async {
|
||||||
assert(currency == CryptoCurrency.eth || contractAddress != null);
|
assert(currency == CryptoCurrency.eth || contractAddress != null);
|
||||||
|
@ -115,7 +116,7 @@ class EthereumClient {
|
||||||
|
|
||||||
final signedTransaction = await _client!.signTransaction(privateKey, transaction);
|
final signedTransaction = await _client!.signTransaction(privateKey, transaction);
|
||||||
|
|
||||||
final estimatedGas;
|
final BigInt estimatedGas;
|
||||||
final Function _sendTransaction;
|
final Function _sendTransaction;
|
||||||
|
|
||||||
if (_isEthereum) {
|
if (_isEthereum) {
|
||||||
|
@ -129,14 +130,10 @@ class EthereumClient {
|
||||||
address: EthereumAddress.fromHex(contractAddress!),
|
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 {
|
_sendTransaction = () async {
|
||||||
await erc20.transfer(
|
await erc20.transfer(
|
||||||
EthereumAddress.fromHex(toAddress),
|
EthereumAddress.fromHex(toAddress),
|
||||||
_amount,
|
BigInt.parse(amount),
|
||||||
credentials: privateKey,
|
credentials: privateKey,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -147,6 +144,7 @@ class EthereumClient {
|
||||||
amount: amount,
|
amount: amount,
|
||||||
fee: estimatedGas * price.getInWei,
|
fee: estimatedGas * price.getInWei,
|
||||||
sendTransaction: _sendTransaction,
|
sendTransaction: _sendTransaction,
|
||||||
|
exponent: exponent,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
|
|
||||||
class EthereumTransactionCreationException implements Exception {
|
class EthereumTransactionCreationException implements Exception {
|
||||||
final String exceptionMessage;
|
final String exceptionMessage;
|
||||||
|
|
||||||
EthereumTransactionCreationException(
|
EthereumTransactionCreationException(CryptoCurrency currency) :
|
||||||
{this.exceptionMessage = 'Wrong balance. Not enough Ether on your balance.'});
|
this.exceptionMessage = 'Wrong balance. Not enough ${currency.title} on your balance.';
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => exceptionMessage;
|
String toString() => exceptionMessage;
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
const ethereumAmountLength = 12;
|
const ethereumAmountLength = 12;
|
||||||
|
@ -17,10 +15,9 @@ class EthereumFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parseEthereumBigIntAmount(BigInt amount) {
|
static double parseEthereumAmountToDouble(int amount) {
|
||||||
try {
|
try {
|
||||||
double result = amount / BigInt.from(pow(10, 18 - ethereumAmountLength));
|
return amount / ethereumAmountDivider;
|
||||||
return result.toInt();
|
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,30 +147,33 @@ abstract class EthereumWalletBase
|
||||||
final hasMultiDestination = outputs.length > 1;
|
final hasMultiDestination = outputs.length > 1;
|
||||||
final _erc20Balance = balance[_credentials.currency]!;
|
final _erc20Balance = balance[_credentials.currency]!;
|
||||||
BigInt totalAmount = BigInt.zero;
|
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 (hasMultiDestination) {
|
||||||
if (outputs.any((item) => item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) {
|
if (outputs.any((item) => item.sendAll || (item.formattedCryptoAmount ?? 0) <= 0)) {
|
||||||
throw EthereumTransactionCreationException();
|
throw EthereumTransactionCreationException(_credentials.currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
totalAmount =
|
final totalOriginalAmount = EthereumFormatter.parseEthereumAmountToDouble(
|
||||||
BigInt.from(outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0))) *
|
outputs.fold(0, (acc, value) => acc + (value.formattedCryptoAmount ?? 0)));
|
||||||
amountToEthereumMultiplier;
|
totalAmount = BigInt.from(totalOriginalAmount) * amountToEthereumMultiplier;
|
||||||
|
|
||||||
if (_erc20Balance.balance < totalAmount) {
|
if (_erc20Balance.balance < totalAmount) {
|
||||||
throw EthereumTransactionCreationException();
|
throw EthereumTransactionCreationException(_credentials.currency);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final output = outputs.first;
|
final output = outputs.first;
|
||||||
final BigInt allAmount = _erc20Balance.balance - BigInt.from(feeRate(_credentials.priority!));
|
final BigInt allAmount = _erc20Balance.balance - BigInt.from(feeRate(_credentials.priority!));
|
||||||
|
final totalOriginalAmount =
|
||||||
|
EthereumFormatter.parseEthereumAmountToDouble(output.formattedCryptoAmount ?? 0);
|
||||||
totalAmount = output.sendAll
|
totalAmount = output.sendAll
|
||||||
? allAmount
|
? allAmount
|
||||||
: BigInt.from(output.formattedCryptoAmount ?? 0) * amountToEthereumMultiplier;
|
: BigInt.from(totalOriginalAmount) * amountToEthereumMultiplier;
|
||||||
|
|
||||||
if ((output.sendAll && _erc20Balance.balance < totalAmount) ||
|
if (_erc20Balance.balance < totalAmount) {
|
||||||
(!output.sendAll && _erc20Balance.balance <= BigInt.zero)) {
|
throw EthereumTransactionCreationException(_credentials.currency);
|
||||||
throw EthereumTransactionCreationException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,6 +184,7 @@ abstract class EthereumWalletBase
|
||||||
gas: _priorityFees[_credentials.priority!.raw],
|
gas: _priorityFees[_credentials.priority!.raw],
|
||||||
priority: _credentials.priority!,
|
priority: _credentials.priority!,
|
||||||
currency: _credentials.currency,
|
currency: _credentials.currency,
|
||||||
|
exponent: exponent,
|
||||||
contractAddress: _credentials.currency is Erc20Token
|
contractAddress: _credentials.currency is Erc20Token
|
||||||
? (_credentials.currency as Erc20Token).contractAddress
|
? (_credentials.currency as Erc20Token).contractAddress
|
||||||
: null,
|
: null,
|
||||||
|
|
|
@ -1,31 +1,32 @@
|
||||||
|
import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
import 'package:web3dart/crypto.dart';
|
import 'package:web3dart/crypto.dart';
|
||||||
import 'package:web3dart/web3dart.dart';
|
|
||||||
|
|
||||||
class PendingEthereumTransaction with PendingTransaction {
|
class PendingEthereumTransaction with PendingTransaction {
|
||||||
final Function sendTransaction;
|
final Function sendTransaction;
|
||||||
final Uint8List signedTransaction;
|
final Uint8List signedTransaction;
|
||||||
final BigInt fee;
|
final BigInt fee;
|
||||||
final String amount;
|
final String amount;
|
||||||
|
final int exponent;
|
||||||
|
|
||||||
PendingEthereumTransaction({
|
PendingEthereumTransaction({
|
||||||
required this.sendTransaction,
|
required this.sendTransaction,
|
||||||
required this.signedTransaction,
|
required this.signedTransaction,
|
||||||
required this.fee,
|
required this.fee,
|
||||||
required this.amount,
|
required this.amount,
|
||||||
|
required this.exponent,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get amountFormatted =>
|
String get amountFormatted => (BigInt.parse(amount) / BigInt.from(pow(10, exponent))).toString();
|
||||||
EtherAmount.inWei(BigInt.parse(amount)).getValueInUnit(EtherUnit.ether).toString();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> commit() async => await sendTransaction();
|
Future<void> commit() async => await sendTransaction();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get feeFormatted => EtherAmount.inWei(fee).getValueInUnit(EtherUnit.ether).toString();
|
String get feeFormatted => (fee / BigInt.from(pow(10, 18))).toString();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get hex => bytesToHex(signedTransaction, include0x: true);
|
String get hex => bytesToHex(signedTransaction, include0x: true);
|
||||||
|
|
Loading…
Reference in a new issue