From c7cdb99a8feaf96f5e69dc995666a29e7e9d3e1a Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Mon, 30 Jun 2025 19:49:42 +0200 Subject: [PATCH] feat: replace manual BigInt conversion with parseFixed for dEuro Savings (#2344) --- cw_core/lib/parse_fixed.dart | 38 +++++++++++++++++++ .../integrations/deuro_view_model.dart | 5 +-- 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 cw_core/lib/parse_fixed.dart diff --git a/cw_core/lib/parse_fixed.dart b/cw_core/lib/parse_fixed.dart new file mode 100644 index 000000000..2b8a7ec17 --- /dev/null +++ b/cw_core/lib/parse_fixed.dart @@ -0,0 +1,38 @@ +BigInt parseFixed(String value, int? decimals) { + decimals ??= 0; + final multiplier = getMultiplier(decimals); + +// Is it negative? + final negative = (value.substring(0, 1) == "-"); + if (negative) value = value.substring(1); + + if (value == ".") throw Exception("missing value, value, $value"); + +// Split it into a whole and fractional part + final comps = value.split("."); + if (comps.length > 2) { + throw Exception("too many decimal points, value, $value"); + } + + var whole = comps.isNotEmpty ? comps[0] : "0"; + var fraction = (comps.length == 2 ? comps[1] : "0").padRight(decimals, "0"); + + // Check the fraction doesn't exceed our decimals size + if (fraction.length > multiplier.length - 1) { + throw Exception( + "fractional component exceeds decimals, underflow, parseFixed"); + } + + final wholeValue = BigInt.parse(whole); + final fractionValue = BigInt.parse(fraction); + final multiplierValue = BigInt.parse(multiplier); + + var wei = (wholeValue * multiplierValue) + fractionValue; + + if (negative) wei *= BigInt.from(-1); + + return wei; +} + +// Returns a string "1" followed by decimal "0"s +String getMultiplier(int decimals) => "1".padRight(decimals + 1, "0"); diff --git a/lib/view_model/integrations/deuro_view_model.dart b/lib/view_model/integrations/deuro_view_model.dart index eca3c2376..a8bf34dbe 100644 --- a/lib/view_model/integrations/deuro_view_model.dart +++ b/lib/view_model/integrations/deuro_view_model.dart @@ -1,11 +1,10 @@ -import 'dart:math'; - import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/view_model/send/send_view_model_state.dart'; import 'package:cw_core/pending_transaction.dart'; import 'package:cw_core/wallet_type.dart'; +import 'package:cw_core/parse_fixed.dart'; import 'package:mobx/mobx.dart'; part 'deuro_view_model.g.dart'; @@ -82,7 +81,7 @@ abstract class DEuroViewModelBase with Store { Future prepareSavingsEdit(String amountRaw, bool isAdding) async { try { state = TransactionCommitting(); - final amount = BigInt.from(num.parse(amountRaw) * pow(10, 18)); + final amount = parseFixed(amountRaw, 18); final priority = _appStore.settingsStore.priority[WalletType.ethereum]!; transaction = await (isAdding ? ethereum!.addDEuroSaving(_appStore.wallet!, amount, priority)