@glowlabs-org/utils 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -4
- package/dist/cjs/constants/addresses.d.ts +3 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +942 -302
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/abis/erc20.abi.d.ts +13 -0
- package/dist/cjs/lib/abis/forwarderABI.d.ts +99 -0
- package/dist/cjs/lib/hooks/use-forwarder.d.ts +36 -0
- package/dist/esm/constants/addresses.d.ts +3 -0
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +942 -303
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/abis/erc20.abi.d.ts +13 -0
- package/dist/esm/lib/abis/forwarderABI.d.ts +99 -0
- package/dist/esm/lib/hooks/use-forwarder.d.ts +36 -0
- package/package.json +3 -2
- package/src/constants/addresses.ts +34 -0
- package/src/index.ts +2 -0
- package/src/lib/abis/erc20.abi.ts +49 -0
- package/src/lib/abis/forwarderABI.ts +69 -0
- package/src/lib/create-weekly-report/index.ts +149 -47
- package/src/lib/hooks/use-forwarder.ts +564 -0
@@ -149,11 +149,6 @@ export async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
|
149
149
|
usdgWeight <= 0 &&
|
150
150
|
rewardSplit.usdgSplitPercent > 0
|
151
151
|
) {
|
152
|
-
console.log(
|
153
|
-
farm.carbonCreditsProduced,
|
154
|
-
usdgWeight,
|
155
|
-
rewardSplit.usdgSplitPercent
|
156
|
-
);
|
157
152
|
throw new Error(
|
158
153
|
"USDG weight is less than 0 and carbon credits produced is greater than 0"
|
159
154
|
);
|
@@ -163,11 +158,6 @@ export async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
|
163
158
|
glowWeight <= 0 &&
|
164
159
|
rewardSplit.glowSplitPercent > 0
|
165
160
|
) {
|
166
|
-
console.log(
|
167
|
-
farm.weeklyPayment,
|
168
|
-
glowWeight,
|
169
|
-
rewardSplit.glowSplitPercent
|
170
|
-
);
|
171
161
|
throw new Error(
|
172
162
|
"Glow weight is less than 0 and weekly payment is greater than 0"
|
173
163
|
);
|
@@ -178,11 +168,6 @@ export async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
|
178
168
|
usdgWeight <= 0 &&
|
179
169
|
rewardSplit.usdgSplitPercent > 0
|
180
170
|
) {
|
181
|
-
console.log(
|
182
|
-
farm.carbonCreditsProduced,
|
183
|
-
usdgWeight.toString(),
|
184
|
-
rewardSplit.usdgSplitPercent
|
185
|
-
);
|
186
171
|
throw new Error(
|
187
172
|
`USDG weight is less than or equal to 0 and carbon credits produced is greater than 0 for farm ${farm.shortId}`
|
188
173
|
);
|
@@ -192,11 +177,6 @@ export async function createWeeklyReportLegacy(args: CreateWeeklyReportArgs) {
|
|
192
177
|
glowWeight <= 0 &&
|
193
178
|
rewardSplit.glowSplitPercent > 0
|
194
179
|
) {
|
195
|
-
console.log(
|
196
|
-
farm.weeklyPayment,
|
197
|
-
glowWeight.toString(),
|
198
|
-
rewardSplit.glowSplitPercent
|
199
|
-
);
|
200
180
|
throw new Error(
|
201
181
|
`Glow weight is less than or equal to 0 and weekly payment is greater than 0 for farm ${farm.shortId}`
|
202
182
|
);
|
@@ -374,6 +354,7 @@ export async function createWeeklyReport({
|
|
374
354
|
}: CreateWeeklyReportArgs) {
|
375
355
|
const map = new Map<string, MerkleLeaf>();
|
376
356
|
|
357
|
+
// Fetch active farms for the week (source of truth) and audits for the week.
|
377
358
|
const [apiResponse, auditsRes] = await Promise.all([
|
378
359
|
fetchFarmsForWeek(week, gcaUrls, apiUrl),
|
379
360
|
axios.get<Audit[]>(
|
@@ -381,38 +362,119 @@ export async function createWeeklyReport({
|
|
381
362
|
),
|
382
363
|
]);
|
383
364
|
|
384
|
-
const farms = apiResponse.filteredFarms;
|
385
|
-
const audits = auditsRes.data;
|
365
|
+
const farms = apiResponse.filteredFarms; // List of farms active this week.
|
366
|
+
const audits = auditsRes.data; // Audits potentially containing adjusted credits.
|
386
367
|
const rawData = apiResponse.rawData;
|
387
368
|
|
369
|
+
// Map to store the final adjusted credit (as bigint) for each active farm shortId.
|
388
370
|
const shortIdToAdjustedCredit = new Map<string, bigint>();
|
371
|
+
// Set to track shortIds that have been assigned a credit from a valid audit to prevent duplicates.
|
372
|
+
const processedAuditShortIds = new Set<string>();
|
373
|
+
// Set of shortIds from the active farms list for quick lookup.
|
374
|
+
const farmShortIds = new Set(farms.map((f) => String(f.shortId)));
|
389
375
|
|
376
|
+
// Process each audit to extract adjusted credit values for active farms.
|
390
377
|
for (const audit of audits) {
|
391
378
|
const activeShortIds = audit.activeShortIds ?? [];
|
392
379
|
const adjustedCredit =
|
393
380
|
audit.summary?.carbonFootprintAndProduction?.adjustedWeeklyCarbonCredit?.trim();
|
394
381
|
|
382
|
+
// Basic validation: Ensure the audit has a valid numeric credit and lists associated shortIds.
|
395
383
|
if (!adjustedCredit || !NUMERIC_REGEX.test(adjustedCredit))
|
396
384
|
throw new Error(
|
397
385
|
`Invalid adjustedWeeklyCarbonCredit for audit ${audit.id}`
|
398
386
|
);
|
399
387
|
if (activeShortIds.length === 0)
|
400
|
-
throw new Error(`
|
388
|
+
throw new Error(`Audit ${audit.id} has empty activeShortIds`);
|
389
|
+
|
390
|
+
// Separate the shortIds listed in the audit into those that are active this week and those that are not.
|
391
|
+
const auditActiveFarmSids: string[] = [];
|
392
|
+
const auditInactiveFarmSids: string[] = [];
|
393
|
+
for (const sid of activeShortIds) {
|
394
|
+
const sidString = String(sid);
|
395
|
+
if (farmShortIds.has(sidString)) {
|
396
|
+
auditActiveFarmSids.push(sidString);
|
397
|
+
} else {
|
398
|
+
auditInactiveFarmSids.push(sidString);
|
399
|
+
}
|
400
|
+
}
|
401
|
+
|
402
|
+
// --- Audit Validity Checks ---
|
403
|
+
|
404
|
+
// Data Integrity Check: An audit for credit distribution should not mix active and inactive farms for the current week.
|
405
|
+
if (auditActiveFarmSids.length > 0 && auditInactiveFarmSids.length > 0) {
|
406
|
+
throw new Error(
|
407
|
+
`Audit ${
|
408
|
+
audit.id
|
409
|
+
} for week ${week} contains a mix of active farms (${auditActiveFarmSids.join(
|
410
|
+
", "
|
411
|
+
)}) and inactive farms (${auditInactiveFarmSids.join(
|
412
|
+
", "
|
413
|
+
)}). Audits should only contain active farms when distributing credits.`
|
414
|
+
);
|
415
|
+
}
|
401
416
|
|
402
|
-
|
417
|
+
// Skip Audit: If the audit only contains shortIds that are not active this week, it's irrelevant for this report.
|
418
|
+
if (auditActiveFarmSids.length === 0) {
|
419
|
+
continue; // Move to the next audit.
|
420
|
+
}
|
421
|
+
|
422
|
+
// --- Process Valid Audit for Active Farms ---
|
423
|
+
|
424
|
+
// Calculate the credit share per active farm within this audit.
|
425
|
+
const splitValue = new Decimal(adjustedCredit).div(
|
426
|
+
auditActiveFarmSids.length // Divide only by the count of *active* farms found in this audit.
|
427
|
+
);
|
428
|
+
|
429
|
+
// Sanity Check: Ensure the calculated split is not zero.
|
403
430
|
if (splitValue.isZero())
|
404
431
|
throw new Error(
|
405
|
-
`Zero adjustedWeeklyCarbonCredit split in audit ${audit.id}`
|
432
|
+
`Zero adjustedWeeklyCarbonCredit split for active farms in audit ${audit.id}`
|
406
433
|
);
|
407
434
|
|
435
|
+
// Convert the decimal split value to a bigint using the defined precision.
|
408
436
|
const splitBigInt = toBigInt(splitValue, USDG_WEIGHT_DECIMAL_PRECISION);
|
409
|
-
|
410
|
-
|
437
|
+
|
438
|
+
// Dust Check: Ensure that the conversion to bigint didn't truncate the value to zero.
|
439
|
+
if (splitBigInt === BigInt(0)) {
|
440
|
+
throw new Error(
|
441
|
+
`Adjusted credit split for audit ${
|
442
|
+
audit.id
|
443
|
+
} resulted in zero BigInt after conversion for precision ${USDG_WEIGHT_DECIMAL_PRECISION}. Original split value: ${splitValue.toString()}. This might indicate dust loss.`
|
444
|
+
);
|
445
|
+
}
|
446
|
+
|
447
|
+
// Distribute the calculated split value to each active farm associated with this audit.
|
448
|
+
for (const sidString of auditActiveFarmSids) {
|
449
|
+
// Duplicate Check: Ensure this shortId hasn't already received credit from another valid audit this week.
|
450
|
+
if (processedAuditShortIds.has(sidString)) {
|
451
|
+
throw new Error(
|
452
|
+
`ShortId ${sidString} found in multiple valid audits for week ${week}`
|
453
|
+
);
|
454
|
+
}
|
455
|
+
processedAuditShortIds.add(sidString); // Mark this shortId as processed.
|
456
|
+
|
457
|
+
// Store the adjusted credit for this active farm.
|
458
|
+
shortIdToAdjustedCredit.set(sidString, splitBigInt);
|
459
|
+
}
|
460
|
+
} // End of loop through audits.
|
461
|
+
|
462
|
+
// Final Validation: Ensure every farm considered active for this week received an adjusted credit value from a valid audit.
|
463
|
+
for (const farmId of farmShortIds) {
|
464
|
+
if (!shortIdToAdjustedCredit.has(farmId)) {
|
465
|
+
throw new Error(
|
466
|
+
`Farm ${farmId} is active for week ${week} but has no corresponding adjusted credit found in any valid audit.`
|
467
|
+
);
|
468
|
+
}
|
411
469
|
}
|
412
470
|
|
413
|
-
|
471
|
+
// --- Start Calculation of Merkle Tree Weights ---
|
472
|
+
|
473
|
+
let totalCreditsProduced18dp = BigInt(0); // Raw total from farm data, for reporting/comparison.
|
414
474
|
|
475
|
+
// Iterate through each active farm to calculate its contribution to the Merkle tree leaves.
|
415
476
|
for (const farm of farms) {
|
477
|
+
// Basic checks for farm data consistency.
|
416
478
|
if (farm.status === "Unassigned") {
|
417
479
|
throw new Error(`farm ${farm.shortId} is unassigned`);
|
418
480
|
}
|
@@ -429,11 +491,13 @@ export async function createWeeklyReport({
|
|
429
491
|
);
|
430
492
|
}
|
431
493
|
|
494
|
+
// Accumulate the reported carbon credits (18 decimal places).
|
432
495
|
totalCreditsProduced18dp += parseUnits(
|
433
496
|
customToFixed(farm.carbonCreditsProduced, 18),
|
434
497
|
18
|
435
498
|
);
|
436
499
|
|
500
|
+
// Validate reward split percentages add up to 1 (within tolerance).
|
437
501
|
const sumGlow = farm.rewardSplits.reduce(
|
438
502
|
(acc: number, r: any) => acc + r.glowSplitPercent,
|
439
503
|
0
|
@@ -448,49 +512,62 @@ export async function createWeeklyReport({
|
|
448
512
|
if (Math.abs(sumUSDG - 1) > percentTolerance)
|
449
513
|
throw new Error(`USDG splits ≠1 for farm ${farm.shortId}`);
|
450
514
|
|
515
|
+
// Get the base GLOW payment for the farm, converted to bigint with appropriate precision.
|
451
516
|
const glowBase = parseUnits(
|
452
517
|
customToFixed(farm.weeklyPayment, GLOW_WEIGHT_DECIMAL_PRECISION),
|
453
518
|
GLOW_WEIGHT_DECIMAL_PRECISION
|
454
519
|
);
|
455
520
|
|
521
|
+
// Retrieve the pre-calculated adjusted credit for this farm. Should always exist due to prior checks.
|
456
522
|
const adjustedCreditBigInt =
|
457
523
|
shortIdToAdjustedCredit.get(String(farm.shortId)) ?? BigInt(0);
|
458
524
|
|
525
|
+
// Sanity check (likely redundant due to earlier checks, but safe).
|
459
526
|
if (adjustedCreditBigInt <= BigInt(0))
|
460
527
|
throw new Error(
|
461
528
|
`Adjusted credit is less than or equal to 0 for farm ${farm.shortId}`
|
462
529
|
);
|
463
530
|
|
531
|
+
// Process each reward split recipient for this farm.
|
464
532
|
for (const split of farm.rewardSplits) {
|
533
|
+
// Calculate the GLOW weight for this recipient based on the farm's weekly payment and split percentage.
|
465
534
|
const glowWeight = multiplyBigIntByDecimalPercentage(
|
466
535
|
glowBase,
|
467
536
|
GLOW_WEIGHT_DECIMAL_PRECISION,
|
468
537
|
split.glowSplitPercent
|
469
538
|
);
|
539
|
+
// Calculate the USDG weight for this recipient based on the farm's *adjusted* credit and split percentage.
|
470
540
|
const usdgWeight = multiplyBigIntByDecimalPercentage(
|
471
541
|
adjustedCreditBigInt,
|
472
542
|
USDG_WEIGHT_DECIMAL_PRECISION,
|
473
543
|
split.usdgSplitPercent
|
474
544
|
);
|
475
545
|
|
546
|
+
// Dust Loss Checks: Ensure non-zero percentages didn't result in zero weight due to precision limits.
|
476
547
|
if (
|
477
548
|
split.usdgSplitPercent > 0 &&
|
478
549
|
adjustedCreditBigInt > BigInt(0) &&
|
479
550
|
usdgWeight === BigInt(0)
|
480
551
|
)
|
481
|
-
throw new Error(
|
552
|
+
throw new Error(
|
553
|
+
`USDG dust lost for farm ${farm.shortId} wallet ${split.walletAddress}`
|
554
|
+
);
|
482
555
|
if (
|
483
556
|
split.glowSplitPercent > 0 &&
|
484
557
|
glowBase > BigInt(0) &&
|
485
558
|
glowWeight === BigInt(0)
|
486
559
|
)
|
487
|
-
throw new Error(
|
560
|
+
throw new Error(
|
561
|
+
`Glow dust lost for farm ${farm.shortId} wallet ${split.walletAddress}`
|
562
|
+
);
|
488
563
|
|
564
|
+
// Overflow Check: Ensure individual leaf weights don't exceed the maximum allowed.
|
489
565
|
if (glowWeight > MAX_WEIGHT || usdgWeight > MAX_WEIGHT)
|
490
566
|
throw new Error(
|
491
567
|
`Leaf weight overflow on wallet ${split.walletAddress}`
|
492
568
|
);
|
493
569
|
|
570
|
+
// Accumulate the calculated weights into the map for the recipient wallet.
|
494
571
|
accumulateLeafWeights(
|
495
572
|
split.walletAddress,
|
496
573
|
{ wallet: split.walletAddress, glowWeight, usdgWeight },
|
@@ -499,27 +576,33 @@ export async function createWeeklyReport({
|
|
499
576
|
}
|
500
577
|
}
|
501
578
|
|
579
|
+
// --- Finalize Merkle Tree and Generate Report Data ---
|
580
|
+
|
581
|
+
// Convert the accumulated weights map into the final list of leaves for the tree.
|
502
582
|
const finalizedLeaves: FinalizedLeaf[] = Array.from(map.values()).map(
|
503
583
|
({ wallet, glowWeight, usdgWeight }) => ({
|
504
584
|
wallet,
|
505
|
-
glowWeight: glowWeight.toString(),
|
585
|
+
glowWeight: glowWeight.toString(), // Convert BigInts to strings for hashing/reporting.
|
506
586
|
usdgWeight: usdgWeight.toString(),
|
507
587
|
})
|
508
588
|
);
|
509
589
|
|
590
|
+
// Hash each leaf according to the defined structure.
|
510
591
|
const hashedLeaves = finalizedLeaves.map((leaf) =>
|
511
592
|
hashLeaf({
|
512
593
|
address: leaf.wallet,
|
513
594
|
glowWeight: leaf.glowWeight,
|
514
|
-
usdcWeight: leaf.usdgWeight,
|
595
|
+
usdcWeight: leaf.usdgWeight, // Note: Parameter name inconsistency (usdc vs usdg)
|
515
596
|
})
|
516
597
|
);
|
517
598
|
|
599
|
+
// Build the Merkle tree.
|
518
600
|
const merkleTree = new MerkleTree(hashedLeaves, ethers.utils.keccak256, {
|
519
|
-
sort: true,
|
601
|
+
sort: true, // Ensure consistent tree structure.
|
520
602
|
});
|
521
|
-
const merkleRoot = merkleTree.getHexRoot();
|
603
|
+
const merkleRoot = merkleTree.getHexRoot(); // Get the root hash.
|
522
604
|
|
605
|
+
// Calculate the total weights across all finalized leaves.
|
523
606
|
const totalGlowWeight = finalizedLeaves.reduce(
|
524
607
|
(acc, { glowWeight }) => acc.add(glowWeight),
|
525
608
|
ethers.BigNumber.from(0)
|
@@ -529,23 +612,29 @@ export async function createWeeklyReport({
|
|
529
612
|
ethers.BigNumber.from(0)
|
530
613
|
);
|
531
614
|
|
615
|
+
// Total Weight Overflow Checks: Ensure sums don't exceed maximum.
|
532
616
|
if (totalGlowWeight.toBigInt() > MAX_WEIGHT)
|
533
617
|
throw new Error("Total glow weight overflow");
|
534
618
|
if (totalUSDGWeight.toBigInt() > MAX_WEIGHT)
|
535
619
|
throw new Error("Total USDG weight overflow");
|
536
620
|
|
621
|
+
// Generate Merkle proofs for each leaf and verify them.
|
537
622
|
const leavesWithProofs = finalizedLeaves.map((leaf) => {
|
538
623
|
const hashed = hashLeaf({
|
539
624
|
address: leaf.wallet,
|
540
625
|
glowWeight: leaf.glowWeight,
|
541
|
-
usdcWeight: leaf.usdgWeight,
|
626
|
+
usdcWeight: leaf.usdgWeight, // Note: Parameter name inconsistency
|
542
627
|
});
|
543
628
|
const proof = merkleTree.getHexProof(hashed);
|
544
629
|
if (!merkleTree.verify(proof, hashed, merkleRoot))
|
630
|
+
// Verify proof against the calculated root.
|
545
631
|
throw new Error("Invalid proof for " + leaf.wallet);
|
546
632
|
return { ...leaf, proof };
|
547
633
|
});
|
548
634
|
|
635
|
+
// --- Sanity Checks on Final Weights ---
|
636
|
+
|
637
|
+
// Verify that summing weights from leavesWithProofs matches the earlier reduce calculation.
|
549
638
|
const glowSumProofLoop = leavesWithProofs.reduce(
|
550
639
|
(acc, l) => acc.add(l.glowWeight),
|
551
640
|
ethers.BigNumber.from(0)
|
@@ -568,22 +657,25 @@ export async function createWeeklyReport({
|
|
568
657
|
throw new Error("USDG sum mismatch");
|
569
658
|
}
|
570
659
|
|
660
|
+
// Calculate the total expected credits based on the adjusted values used.
|
571
661
|
const totalExpectedCredits = farms.reduce((acc: Decimal, f: any) => {
|
572
662
|
const adj = shortIdToAdjustedCredit.get(String(f.shortId)) ?? BigInt(0);
|
573
663
|
return acc.plus(fromBigInt(adj, USDG_WEIGHT_DECIMAL_PRECISION));
|
574
664
|
}, new Decimal(0));
|
575
665
|
|
666
|
+
// Convert total USDG weight back to human-readable decimal for deviation check.
|
576
667
|
const totalUSDGWeightHuman = new Decimal(
|
577
668
|
formatUnits(
|
578
669
|
BigInt(totalUSDGWeight.toString()),
|
579
670
|
USDG_WEIGHT_DECIMAL_PRECISION
|
580
671
|
)
|
581
672
|
);
|
673
|
+
// Check deviation between total adjusted credits used and the final sum of USDG weights.
|
582
674
|
if (
|
583
675
|
greaterThanMaxDeviation(
|
584
676
|
totalExpectedCredits.toNumber(),
|
585
677
|
totalUSDGWeightHuman.toNumber(),
|
586
|
-
0.001
|
678
|
+
0.001 // 0.1% tolerance
|
587
679
|
)
|
588
680
|
) {
|
589
681
|
console.error(
|
@@ -595,21 +687,24 @@ export async function createWeeklyReport({
|
|
595
687
|
throw new Error("totalExpectedCredits vs USDG weight deviation >0.1% ");
|
596
688
|
}
|
597
689
|
|
690
|
+
// Convert total Glow weight back to human-readable decimal.
|
598
691
|
const totalGlowWeightHuman = new Decimal(
|
599
692
|
formatUnits(
|
600
693
|
BigInt(totalGlowWeight.toString()),
|
601
694
|
GLOW_WEIGHT_DECIMAL_PRECISION
|
602
695
|
)
|
603
696
|
);
|
697
|
+
// Sum the original weekly protocol fee payments from farm data.
|
604
698
|
const totalProtocolFeePayments = farms.reduce(
|
605
699
|
(acc: number, f: any) => acc + f.weeklyPayment,
|
606
700
|
0
|
607
701
|
);
|
702
|
+
// Check deviation between total glow weight and total protocol fees paid.
|
608
703
|
if (
|
609
704
|
greaterThanMaxDeviation(
|
610
705
|
totalGlowWeightHuman.toNumber(),
|
611
706
|
totalProtocolFeePayments,
|
612
|
-
0.001
|
707
|
+
0.001 // 0.1% tolerance
|
613
708
|
)
|
614
709
|
) {
|
615
710
|
console.error(
|
@@ -621,12 +716,15 @@ export async function createWeeklyReport({
|
|
621
716
|
throw new Error("totalGlowWeight vs protocol fees deviation >0.1% ");
|
622
717
|
}
|
623
718
|
|
719
|
+
// --- Prepare Output Data ---
|
720
|
+
|
721
|
+
// Key statistics for the report.
|
624
722
|
const headlineStats = {
|
625
723
|
weekNumber: week,
|
626
|
-
totalCreditsProduced: formatUnits(totalCreditsProduced18dp, 18),
|
724
|
+
totalCreditsProduced: formatUnits(totalCreditsProduced18dp, 18), // Original reported total
|
627
725
|
totalCreditsProducedBN: totalCreditsProduced18dp.toString(),
|
628
|
-
totalGlowWeightInFinalized: totalGlowWeight.toString(),
|
629
|
-
totalGlowWeightHuman: totalGlowWeightHuman.toString(),
|
726
|
+
totalGlowWeightInFinalized: totalGlowWeight.toString(), // Total weight as BigNumber string
|
727
|
+
totalGlowWeightHuman: totalGlowWeightHuman.toString(), // Total weight as human-readable decimal
|
630
728
|
totalUSDGWeightInFinalized: totalUSDGWeight.toString(),
|
631
729
|
totalUSDGWeightHuman: totalUSDGWeightHuman.toString(),
|
632
730
|
root: merkleRoot,
|
@@ -634,6 +732,7 @@ export async function createWeeklyReport({
|
|
634
732
|
usdgWeightDecimals: USDG_WEIGHT_DECIMAL_PRECISION,
|
635
733
|
};
|
636
734
|
|
735
|
+
// List of shortIds and their final adjusted credit value (human-readable).
|
637
736
|
const shortIdAdjustedList = Array.from(shortIdToAdjustedCredit.entries()).map(
|
638
737
|
([shortId, creditBigInt]) => ({
|
639
738
|
shortId,
|
@@ -644,6 +743,7 @@ export async function createWeeklyReport({
|
|
644
743
|
})
|
645
744
|
);
|
646
745
|
|
746
|
+
// Detailed comparison between originally reported credits and adjusted credits for each farm.
|
647
747
|
const creditsDeviationList = farms.map((farm: any) => {
|
648
748
|
const adj = shortIdToAdjustedCredit.get(String(farm.shortId)) ?? BigInt(0);
|
649
749
|
const adjusted = fromBigInt(adj, USDG_WEIGHT_DECIMAL_PRECISION);
|
@@ -651,6 +751,7 @@ export async function createWeeklyReport({
|
|
651
751
|
let deviation: Decimal;
|
652
752
|
let absDeviation: Decimal;
|
653
753
|
let deviationPercent: Decimal;
|
754
|
+
// Handle division by zero if produced is zero.
|
654
755
|
if (produced.isZero() && adjusted.isZero()) {
|
655
756
|
deviation = new Decimal(0);
|
656
757
|
absDeviation = new Decimal(0);
|
@@ -659,7 +760,7 @@ export async function createWeeklyReport({
|
|
659
760
|
deviation = produced.minus(adjusted);
|
660
761
|
absDeviation = deviation.abs();
|
661
762
|
deviationPercent = deviation
|
662
|
-
.div(produced.isZero() ? 1 : produced)
|
763
|
+
.div(produced.isZero() ? 1 : produced) // Avoid division by zero
|
663
764
|
.mul(100);
|
664
765
|
}
|
665
766
|
return {
|
@@ -672,13 +773,14 @@ export async function createWeeklyReport({
|
|
672
773
|
};
|
673
774
|
});
|
674
775
|
|
776
|
+
// Return all calculated data.
|
675
777
|
return {
|
676
778
|
headlineStats,
|
677
|
-
finalizedLeaves,
|
678
|
-
leavesWithProofs,
|
679
|
-
farms,
|
680
|
-
rawData,
|
681
|
-
shortIdAdjustedList,
|
682
|
-
creditsDeviationList,
|
779
|
+
finalizedLeaves, // Leaves without proofs (for potential use cases)
|
780
|
+
leavesWithProofs, // Leaves with proofs (primary data for distribution)
|
781
|
+
farms, // Original filtered farm data
|
782
|
+
rawData, // Raw GCA responses
|
783
|
+
shortIdAdjustedList, // List of adjusted credits per farm
|
784
|
+
creditsDeviationList, // Detailed deviation report per farm
|
683
785
|
};
|
684
786
|
}
|