@namehash/ens-referrals 1.10.0 → 1.10.1
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/dist/index.cjs +103 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +103 -56
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -69,6 +69,7 @@ __export(index_exports, {
|
|
|
69
69
|
buildUnrankedReferrerMetricsPieSplit: () => buildUnrankedReferrerMetricsPieSplit,
|
|
70
70
|
buildUnrankedReferrerMetricsRevShareCap: () => buildUnrankedReferrerMetricsRevShareCap,
|
|
71
71
|
calcBaseReferralProgramEditionStatus: () => calcBaseReferralProgramEditionStatus,
|
|
72
|
+
calcBaseRevenueContribution: () => calcBaseRevenueContribution,
|
|
72
73
|
calcReferralProgramEditionStatusPieSplit: () => calcReferralProgramEditionStatusPieSplit,
|
|
73
74
|
calcReferralProgramEditionStatusRevShareCap: () => calcReferralProgramEditionStatusRevShareCap,
|
|
74
75
|
calcReferrerAwardPoolSharePieSplit: () => calcReferrerAwardPoolSharePieSplit,
|
|
@@ -508,6 +509,45 @@ function priceUsdc(amount) {
|
|
|
508
509
|
currency: CurrencyIds.USDC
|
|
509
510
|
};
|
|
510
511
|
}
|
|
512
|
+
function isPriceCurrencyEqual(priceA, priceB) {
|
|
513
|
+
return priceA.currency === priceB.currency;
|
|
514
|
+
}
|
|
515
|
+
function addPrices(...prices) {
|
|
516
|
+
const firstPrice = prices[0];
|
|
517
|
+
const allPricesInSameCurrency = prices.every((price) => isPriceCurrencyEqual(firstPrice, price));
|
|
518
|
+
if (allPricesInSameCurrency === false) {
|
|
519
|
+
throw new Error("All prices must have the same currency to be added together.");
|
|
520
|
+
}
|
|
521
|
+
const { currency } = firstPrice;
|
|
522
|
+
return prices.reduce(
|
|
523
|
+
(acc, price) => ({
|
|
524
|
+
amount: acc.amount + price.amount,
|
|
525
|
+
currency
|
|
526
|
+
}),
|
|
527
|
+
{
|
|
528
|
+
amount: 0n,
|
|
529
|
+
currency: firstPrice.currency
|
|
530
|
+
}
|
|
531
|
+
);
|
|
532
|
+
}
|
|
533
|
+
function subtractPrice(a, b) {
|
|
534
|
+
if (!isPriceCurrencyEqual(a, b)) {
|
|
535
|
+
throw new Error("All prices must have the same currency to be subtracted.");
|
|
536
|
+
}
|
|
537
|
+
const resultAmount = a.amount - b.amount;
|
|
538
|
+
if (resultAmount < 0n) {
|
|
539
|
+
throw new Error("subtractPrice result must be non-negative.");
|
|
540
|
+
}
|
|
541
|
+
return { amount: resultAmount, currency: a.currency };
|
|
542
|
+
}
|
|
543
|
+
function minPrice(...prices) {
|
|
544
|
+
const firstPrice = prices[0];
|
|
545
|
+
const allPricesInSameCurrency = prices.every((price) => isPriceCurrencyEqual(firstPrice, price));
|
|
546
|
+
if (allPricesInSameCurrency === false) {
|
|
547
|
+
throw new Error("All prices must have the same currency to be compared.");
|
|
548
|
+
}
|
|
549
|
+
return prices.reduce((acc, price) => price.amount < acc.amount ? price : acc);
|
|
550
|
+
}
|
|
511
551
|
function scalePrice(price, scaleFactor) {
|
|
512
552
|
const scaledAmount = scaleBigintByNumber(price.amount, scaleFactor);
|
|
513
553
|
return {
|
|
@@ -1062,6 +1102,11 @@ var buildReferralProgramRulesRevShareCap = (awardPool, minBaseRevenueContributio
|
|
|
1062
1102
|
validateReferralProgramRulesRevShareCap(result);
|
|
1063
1103
|
return result;
|
|
1064
1104
|
};
|
|
1105
|
+
function calcBaseRevenueContribution(rules, duration) {
|
|
1106
|
+
return priceUsdc(
|
|
1107
|
+
rules.baseAnnualRevenueContribution.amount * BigInt(duration) / BigInt(SECONDS_PER_YEAR)
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1065
1110
|
function isReferrerQualifiedRevShareCap(referrer, totalBaseRevenueContribution, rules) {
|
|
1066
1111
|
const isAdminDisqualified = rules.adminActions.some(
|
|
1067
1112
|
(a) => a.referrer === referrer && a.actionType === AdminActionTypes.Disqualification
|
|
@@ -2420,8 +2465,9 @@ var validateReferrerMetricsRevShareCap = (metrics, rules) => {
|
|
|
2420
2465
|
makePriceUsdcSchema("ReferrerMetricsRevShareCap.totalBaseRevenueContribution").parse(
|
|
2421
2466
|
metrics.totalBaseRevenueContribution
|
|
2422
2467
|
);
|
|
2423
|
-
const expectedTotalBaseRevenueContribution =
|
|
2424
|
-
rules
|
|
2468
|
+
const expectedTotalBaseRevenueContribution = calcBaseRevenueContribution(
|
|
2469
|
+
rules,
|
|
2470
|
+
metrics.totalIncrementalDuration
|
|
2425
2471
|
);
|
|
2426
2472
|
if (metrics.totalBaseRevenueContribution.amount !== expectedTotalBaseRevenueContribution.amount) {
|
|
2427
2473
|
throw new Error(
|
|
@@ -2430,8 +2476,9 @@ var validateReferrerMetricsRevShareCap = (metrics, rules) => {
|
|
|
2430
2476
|
}
|
|
2431
2477
|
};
|
|
2432
2478
|
var buildReferrerMetricsRevShareCap = (metrics, rules) => {
|
|
2433
|
-
const totalBaseRevenueContribution =
|
|
2434
|
-
rules
|
|
2479
|
+
const totalBaseRevenueContribution = calcBaseRevenueContribution(
|
|
2480
|
+
rules,
|
|
2481
|
+
metrics.totalIncrementalDuration
|
|
2435
2482
|
);
|
|
2436
2483
|
const result = {
|
|
2437
2484
|
...metrics,
|
|
@@ -2605,71 +2652,71 @@ function sortReferralEvents(events) {
|
|
|
2605
2652
|
}
|
|
2606
2653
|
|
|
2607
2654
|
// src/award-models/rev-share-cap/leaderboard.ts
|
|
2608
|
-
var bigintMin = (a, b) => a < b ? a : b;
|
|
2609
2655
|
var buildReferrerLeaderboardRevShareCap = (events, rules, accurateAsOf) => {
|
|
2610
2656
|
const sortedEvents = sortReferralEvents(events);
|
|
2611
2657
|
const referrerStates = /* @__PURE__ */ new Map();
|
|
2612
|
-
let awardPoolRemaining = rules.awardPool
|
|
2658
|
+
let awardPoolRemaining = rules.awardPool;
|
|
2613
2659
|
for (const event of sortedEvents) {
|
|
2614
|
-
const
|
|
2615
|
-
let
|
|
2616
|
-
if (!
|
|
2617
|
-
|
|
2660
|
+
const referrerId = event.referrer;
|
|
2661
|
+
let referrerState = referrerStates.get(referrerId);
|
|
2662
|
+
if (!referrerState) {
|
|
2663
|
+
referrerState = {
|
|
2618
2664
|
totalReferrals: 0,
|
|
2619
2665
|
totalIncrementalDuration: 0,
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2666
|
+
totalRevenueContribution: priceEth(0n),
|
|
2667
|
+
hasQualified: false,
|
|
2668
|
+
cappedAward: priceUsdc(0n)
|
|
2623
2669
|
};
|
|
2624
|
-
referrerStates.set(
|
|
2670
|
+
referrerStates.set(referrerId, referrerState);
|
|
2625
2671
|
}
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
rules
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
)
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
const incrementalBaseRevenueAmount = rules.baseAnnualRevenueContribution.amount * BigInt(event.incrementalDuration) / BigInt(SECONDS_PER_YEAR);
|
|
2672
|
+
referrerState.totalReferrals += 1;
|
|
2673
|
+
referrerState.totalIncrementalDuration += event.incrementalDuration;
|
|
2674
|
+
referrerState.totalRevenueContribution = addPrices(
|
|
2675
|
+
referrerState.totalRevenueContribution,
|
|
2676
|
+
event.incrementalRevenueContribution
|
|
2677
|
+
);
|
|
2678
|
+
const totalBaseRevenue = calcBaseRevenueContribution(
|
|
2679
|
+
rules,
|
|
2680
|
+
referrerState.totalIncrementalDuration
|
|
2681
|
+
);
|
|
2682
|
+
const isNowQualified = isReferrerQualifiedRevShareCap(referrerId, totalBaseRevenue, rules);
|
|
2683
|
+
if (isNowQualified && !referrerState.hasQualified) {
|
|
2684
|
+
const accumulatedUncappedAward = scalePrice(totalBaseRevenue, rules.maxBaseRevenueShare);
|
|
2685
|
+
const incrementalCappedAward = minPrice(accumulatedUncappedAward, awardPoolRemaining);
|
|
2686
|
+
referrerState.cappedAward = addPrices(referrerState.cappedAward, incrementalCappedAward);
|
|
2687
|
+
awardPoolRemaining = subtractPrice(awardPoolRemaining, incrementalCappedAward);
|
|
2688
|
+
referrerState.hasQualified = true;
|
|
2689
|
+
} else if (referrerState.hasQualified) {
|
|
2690
|
+
const incrementalBaseRevenue = calcBaseRevenueContribution(rules, event.incrementalDuration);
|
|
2646
2691
|
const incrementalUncappedAward = scalePrice(
|
|
2647
|
-
|
|
2692
|
+
incrementalBaseRevenue,
|
|
2648
2693
|
rules.maxBaseRevenueShare
|
|
2649
|
-
)
|
|
2650
|
-
const incrementalCappedAward =
|
|
2651
|
-
|
|
2652
|
-
awardPoolRemaining
|
|
2694
|
+
);
|
|
2695
|
+
const incrementalCappedAward = minPrice(incrementalUncappedAward, awardPoolRemaining);
|
|
2696
|
+
referrerState.cappedAward = addPrices(referrerState.cappedAward, incrementalCappedAward);
|
|
2697
|
+
awardPoolRemaining = subtractPrice(awardPoolRemaining, incrementalCappedAward);
|
|
2653
2698
|
}
|
|
2654
2699
|
}
|
|
2655
|
-
const sortedEntries = [...referrerStates.entries()].sort(
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2700
|
+
const sortedEntries = [...referrerStates.entries()].sort(
|
|
2701
|
+
([referrerIdA, referrerStateA], [referrerIdB, referrerStateB]) => {
|
|
2702
|
+
if (referrerStateB.cappedAward.amount !== referrerStateA.cappedAward.amount) {
|
|
2703
|
+
return referrerStateB.cappedAward.amount > referrerStateA.cappedAward.amount ? 1 : -1;
|
|
2704
|
+
}
|
|
2705
|
+
if (referrerStateB.totalIncrementalDuration !== referrerStateA.totalIncrementalDuration) {
|
|
2706
|
+
return referrerStateB.totalIncrementalDuration - referrerStateA.totalIncrementalDuration;
|
|
2707
|
+
}
|
|
2708
|
+
if (referrerIdB > referrerIdA) return 1;
|
|
2709
|
+
if (referrerIdB < referrerIdA) return -1;
|
|
2710
|
+
return 0;
|
|
2661
2711
|
}
|
|
2662
|
-
|
|
2663
|
-
if (b < a) return -1;
|
|
2664
|
-
return 0;
|
|
2665
|
-
});
|
|
2712
|
+
);
|
|
2666
2713
|
const awardedReferrers = sortedEntries.map(
|
|
2667
|
-
([
|
|
2714
|
+
([referrerId, referrerState], index) => {
|
|
2668
2715
|
const baseMetrics = buildReferrerMetrics(
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2716
|
+
referrerId,
|
|
2717
|
+
referrerState.totalReferrals,
|
|
2718
|
+
referrerState.totalIncrementalDuration,
|
|
2719
|
+
referrerState.totalRevenueContribution
|
|
2673
2720
|
);
|
|
2674
2721
|
const revShareMetrics = buildReferrerMetricsRevShareCap(baseMetrics, rules);
|
|
2675
2722
|
const rankedMetrics = buildRankedReferrerMetricsRevShareCap(
|
|
@@ -2684,14 +2731,14 @@ var buildReferrerLeaderboardRevShareCap = (events, rules, accurateAsOf) => {
|
|
|
2684
2731
|
return buildAwardedReferrerMetricsRevShareCap(
|
|
2685
2732
|
rankedMetrics,
|
|
2686
2733
|
uncappedAward,
|
|
2687
|
-
|
|
2734
|
+
referrerState.cappedAward,
|
|
2688
2735
|
rules
|
|
2689
2736
|
);
|
|
2690
2737
|
}
|
|
2691
2738
|
);
|
|
2692
2739
|
const aggregatedMetrics = buildAggregatedReferrerMetricsRevShareCap(
|
|
2693
2740
|
awardedReferrers,
|
|
2694
|
-
|
|
2741
|
+
awardPoolRemaining
|
|
2695
2742
|
);
|
|
2696
2743
|
const referrers = new Map(awardedReferrers.map((r) => [r.referrer, r]));
|
|
2697
2744
|
return { awardModel: rules.awardModel, rules, aggregatedMetrics, referrers, accurateAsOf };
|