feat: replace manual BigInt conversion with parseFixed for dEuro Savings (#2344)
Konstantin Ullrich committed
Jun 30, 2025 at 19:49 UTC
c7cdb99a8feaf96f5e69dc995666a29e7e9d3e1a
2 files changed
+40
-3
cw_core/lib/parse_fixed.dart
new
+38
@@ -0,0 +1,38 @@
1
+BigInt parseFixed(String value, int? decimals) {
2
+ decimals ??= 0;
3
+ final multiplier = getMultiplier(decimals);
4
+
5
+// Is it negative?
6
+ final negative = (value.substring(0, 1) == "-");
7
+ if (negative) value = value.substring(1);
8
+
9
+ if (value == ".") throw Exception("missing value, value, $value");
10
+
11
+// Split it into a whole and fractional part
12
+ final comps = value.split(".");
13
+ if (comps.length > 2) {
14
+ throw Exception("too many decimal points, value, $value");
15
+ }
16
+
17
+ var whole = comps.isNotEmpty ? comps[0] : "0";
18
+ var fraction = (comps.length == 2 ? comps[1] : "0").padRight(decimals, "0");
19
+
20
+ // Check the fraction doesn't exceed our decimals size
21
+ if (fraction.length > multiplier.length - 1) {
22
+ throw Exception(
23
+ "fractional component exceeds decimals, underflow, parseFixed");
24
+ }
25
+
26
+ final wholeValue = BigInt.parse(whole);
27
+ final fractionValue = BigInt.parse(fraction);
28
+ final multiplierValue = BigInt.parse(multiplier);
29
+
30
+ var wei = (wholeValue * multiplierValue) + fractionValue;
31
+
32
+ if (negative) wei *= BigInt.from(-1);
33
+
34
+ return wei;
35
+}
36
+
37
+// Returns a string "1" followed by decimal "0"s
38
+String getMultiplier(int decimals) => "1".padRight(decimals + 1, "0");
lib/view_model/integrations/deuro_view_model.dart
+2
-3
@@ -1,11 +1,10 @@
1
-import 'dart:math';
2
-
1
import 'package:cake_wallet/core/execution_state.dart';
2
import 'package:cake_wallet/ethereum/ethereum.dart';
3
import 'package:cake_wallet/store/app_store.dart';
4
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
5
import 'package:cw_core/pending_transaction.dart';
6
import 'package:cw_core/wallet_type.dart';
7
+import 'package:cw_core/parse_fixed.dart';
8
import 'package:mobx/mobx.dart';
9
10
part 'deuro_view_model.g.dart';
@@ -82,7 +81,7 @@ abstract class DEuroViewModelBase with Store {
81
Future<void> prepareSavingsEdit(String amountRaw, bool isAdding) async {
82
try {
83
state = TransactionCommitting();
85
- final amount = BigInt.from(num.parse(amountRaw) * pow(10, 18));
84
+ final amount = parseFixed(amountRaw, 18);
85
final priority = _appStore.settingsStore.priority[WalletType.ethereum]!;
86
transaction = await (isAdding
87
? ethereum!.addDEuroSaving(_appStore.wallet!, amount, priority)