|
1 | | -import { |
2 | | - type Duration, |
3 | | - type PriceEth, |
4 | | - type PriceUsdc, |
5 | | - priceEth, |
6 | | - priceUsdc, |
7 | | - scalePrice, |
8 | | -} from "@ensnode/ensnode-sdk"; |
| 1 | +import { type Duration, type PriceEth, type PriceUsdc, priceEth } from "@ensnode/ensnode-sdk"; |
9 | 2 | import { makePriceEthSchema, makePriceUsdcSchema } from "@ensnode/ensnode-sdk/internal"; |
10 | 3 |
|
11 | 4 | import { validateNonNegativeInteger } from "../../number"; |
12 | 5 | import { validateDuration } from "../../time"; |
13 | | -import type { RankedReferrerMetricsRevShareLimit } from "./metrics"; |
14 | | -import type { ReferralProgramRulesRevShareLimit } from "./rules"; |
| 6 | +import type { AwardedReferrerMetricsRevShareLimit } from "./metrics"; |
15 | 7 |
|
16 | 8 | /** |
17 | | - * Represents aggregated metrics for a list of {@link RankedReferrerMetricsRevShareLimit}. |
| 9 | + * Represents aggregated metrics for a list of referrers on a rev-share-limit leaderboard. |
18 | 10 | */ |
19 | 11 | export interface AggregatedReferrerMetricsRevShareLimit { |
20 | 12 | /** |
21 | | - * @invariant The sum of `totalReferrals` across all {@link RankedReferrerMetricsRevShareLimit} in the list. |
| 13 | + * @invariant The sum of `totalReferrals` across all referrers in the list. |
22 | 14 | * @invariant Guaranteed to be a non-negative integer (>= 0) |
23 | 15 | */ |
24 | 16 | grandTotalReferrals: number; |
25 | 17 |
|
26 | 18 | /** |
27 | | - * @invariant The sum of `totalIncrementalDuration` across all {@link RankedReferrerMetricsRevShareLimit} in the list. |
| 19 | + * @invariant The sum of `totalIncrementalDuration` across all referrers in the list. |
28 | 20 | */ |
29 | 21 | grandTotalIncrementalDuration: Duration; |
30 | 22 |
|
31 | 23 | /** |
32 | 24 | * The total revenue contribution in ETH to the ENS DAO from all referrals |
33 | 25 | * across all referrers on the leaderboard. |
34 | 26 | * |
35 | | - * This is the sum of `totalRevenueContribution` across all {@link RankedReferrerMetricsRevShareLimit} in the list. |
| 27 | + * This is the sum of `totalRevenueContribution` across all referrers in the list. |
36 | 28 | * |
37 | 29 | * @invariant Guaranteed to be a valid PriceEth with non-negative amount (>= 0n) |
38 | 30 | */ |
39 | 31 | grandTotalRevenueContribution: PriceEth; |
40 | 32 |
|
41 | 33 | /** |
42 | | - * The remaining amount in the award pool after subtracting the total potential awards |
43 | | - * (capped at 0 if total potential awards exceed the pool). |
| 34 | + * The remaining amount in the award pool after subtracting all qualified awards |
| 35 | + * claimed during the sequential race processing. |
44 | 36 | * |
45 | 37 | * @invariant Guaranteed to be a valid PriceUsdc with non-negative amount (>= 0n) |
46 | 38 | */ |
@@ -75,65 +67,41 @@ export const validateAggregatedReferrerMetricsRevShareLimit = ( |
75 | 67 | }; |
76 | 68 |
|
77 | 69 | /** |
78 | | - * Builds aggregated rev-share-limit metrics from a complete, globally ranked list of referrers. |
| 70 | + * Builds aggregated rev-share-limit metrics from a complete list of referrers and |
| 71 | + * the award pool remaining after sequential race processing. |
79 | 72 | * |
80 | | - * **IMPORTANT: This function expects a complete ranking of all referrers.** |
| 73 | + * **IMPORTANT: This function expects a complete list of all referrers.** |
81 | 74 | * |
82 | | - * @param referrers - Must be a complete, globally ranked list of {@link RankedReferrerMetricsRevShareLimit} |
83 | | - * where ranks start at 1 and are consecutive. |
84 | | - * **This must NOT be a paginated or partial slice of the rankings.** |
| 75 | + * @param referrers - Must be a complete list of referrers with their totals. |
| 76 | + * **This must NOT be a paginated or partial slice.** |
85 | 77 | * |
86 | | - * @param rules - The {@link ReferralProgramRulesRevShareLimit} object that define qualification criteria. |
| 78 | + * @param awardPoolRemaining - The amount remaining in the award pool after the sequential |
| 79 | + * race algorithm has processed all events. |
87 | 80 | * |
88 | 81 | * @returns Aggregated metrics including totals across all referrers and the award pool remaining. |
89 | | - * |
90 | | - * @remarks |
91 | | - * - If you need to work with paginated data, aggregate the full ranking first before |
92 | | - * calling this function, or call this function on the complete dataset and then paginate |
93 | | - * the results. |
94 | 82 | */ |
95 | 83 | export const buildAggregatedReferrerMetricsRevShareLimit = ( |
96 | | - referrers: RankedReferrerMetricsRevShareLimit[], |
97 | | - rules: ReferralProgramRulesRevShareLimit, |
98 | | -): { aggregatedMetrics: AggregatedReferrerMetricsRevShareLimit; scalingFactor: number } => { |
| 84 | + referrers: AwardedReferrerMetricsRevShareLimit[], |
| 85 | + awardPoolRemaining: PriceUsdc, |
| 86 | +): AggregatedReferrerMetricsRevShareLimit => { |
99 | 87 | let grandTotalReferrals = 0; |
100 | 88 | let grandTotalIncrementalDuration = 0; |
101 | 89 | let grandTotalRevenueContributionAmount = 0n; |
102 | | - let totalPotentialAwardsAmount = 0n; |
103 | 90 |
|
104 | 91 | for (const referrer of referrers) { |
105 | 92 | grandTotalReferrals += referrer.totalReferrals; |
106 | 93 | grandTotalIncrementalDuration += referrer.totalIncrementalDuration; |
107 | 94 | grandTotalRevenueContributionAmount += referrer.totalRevenueContribution.amount; |
108 | | - if (referrer.isQualified) { |
109 | | - const potentialAward = scalePrice( |
110 | | - referrer.totalBaseRevenueContribution, |
111 | | - rules.qualifiedRevenueShare, |
112 | | - ); |
113 | | - totalPotentialAwardsAmount += potentialAward.amount; |
114 | | - } |
115 | 95 | } |
116 | 96 |
|
117 | | - const scalingFactor = |
118 | | - totalPotentialAwardsAmount > 0n |
119 | | - ? Math.min(1, Number(rules.totalAwardPoolValue.amount) / Number(totalPotentialAwardsAmount)) |
120 | | - : 1; |
121 | | - |
122 | | - const cappedTotalPotentialAwards = |
123 | | - totalPotentialAwardsAmount < rules.totalAwardPoolValue.amount |
124 | | - ? totalPotentialAwardsAmount |
125 | | - : rules.totalAwardPoolValue.amount; |
126 | | - |
127 | | - const awardPoolRemainingAmount = rules.totalAwardPoolValue.amount - cappedTotalPotentialAwards; |
128 | | - |
129 | 97 | const aggregatedMetrics = { |
130 | 98 | grandTotalReferrals, |
131 | 99 | grandTotalIncrementalDuration, |
132 | 100 | grandTotalRevenueContribution: priceEth(grandTotalRevenueContributionAmount), |
133 | | - awardPoolRemaining: priceUsdc(awardPoolRemainingAmount), |
| 101 | + awardPoolRemaining, |
134 | 102 | } satisfies AggregatedReferrerMetricsRevShareLimit; |
135 | 103 |
|
136 | 104 | validateAggregatedReferrerMetricsRevShareLimit(aggregatedMetrics); |
137 | 105 |
|
138 | | - return { aggregatedMetrics, scalingFactor }; |
| 106 | + return aggregatedMetrics; |
139 | 107 | }; |
0 commit comments