DeepLens V2 ranks wallets using a 5-factor composite score that combines raw DeepBook points with trading behavior metrics. The score ranges from 0 to 100 and is used to assign wallets to one of five competitive tiers.
compositeScore = (0.35 * normalizedPoints) + (0.25 * normalizedVolume) + (0.15 * normalizedTrades) + (0.15 * protocolDiversity) + (0.10 * consistencyRatio)Each component is normalized to the [0, 1] range before weighting. The weighted sum produces a value between 0 and 1, which is then scaled to 0–100 and rounded to two decimal places.
| Component | Weight | Symbol |
|---|---|---|
| Points | 35% | np |
| Volume | 25% | nv |
| Trade Count | 15% | nt |
| Protocol Diversity | 15% | pd |
| Consistency | 10% | cs |
The weights sum to exactly 1.0 and are enforced by a unit test.
1. Normalized Points (35%)
Total lifetime DeepBook Points Program points, normalized against the 99th percentile cap. This is the single most important factor, as it directly reflects cumulative on-chain activity.
Example: If the 99th percentile cap is 100,000 points and a wallet has 50,000 points, np = 0.5.
2. Normalized Volume (25%)
Total USD-denominated trading volume, normalized against the 99th percentile cap. Measures the magnitude of trading activity regardless of point accrual.
Example: If the 99th percentile cap is $1,000,000 and a wallet has traded $500,000, nv = 0.5.
3. Normalized Trade Count (15%)
Number of on-chain trades executed, normalized against the 99th percentile. This rewards active traders who execute many transactions rather than a few large ones.
Example: If the 99th percentile cap is 5,000 trades and a wallet has 2,500, nt = 0.5.
4. Protocol Diversity (15%)
The number of unique protocols a wallet has interacted with, divided by the maximum of 12 tracked protocols. Rewards ecosystem breadth — wallets that use multiple DeFi protocols score higher.
Example: A wallet using 6 of the 12 tracked protocols gets pd = 0.5. Using all 12 gives pd = 1.0. Values above 12 are clamped.
5. Consistency Ratio (10%)
Ratio of current-epoch points to total lifetime points. Measures whether a wallet is still actively earning or has become dormant. Higher ratio = more consistent, ongoing participation.
Example: A wallet with 100,000 total points and 50,000 current points has cs = 0.5. If totalPoints is 0, cs defaults to 0.
Raw values for points, volume, and trade count are capped at the 99th percentile of the entire population before normalization. This prevents a handful of whale wallets from compressing the score distribution for everyone else.
// Compute 99th percentile cap
pointsCap = percentile(allPoints, 0.99)
volumeCap = percentile(allVolumes, 0.99)
tradesCap = percentile(allTrades, 0.99)
// Any wallet above the cap normalizes to 1.0
normalize(val, cap) = min(1, max(0, val / cap))
For protocol diversity and consistency, capping is built into the formula itself (divided by 12 and by totalPoints respectively), so no additional percentile capping is needed.
Each raw metric is transformed to the [0, 1] range using min-max normalization with the 99th percentile as the upper bound:
This ensures:
After normalization and weighting, the final composite ranges from 0 (completely inactive) to 100 (maximum across all dimensions).
The weighted sum of normalized components falls in [0, 1]. This is then scaled:
This gives two decimal places of precision (e.g. 67.84). In practice, very few wallets score above 90, and the median score across 50,000+ wallets tends to be quite low since most wallets have limited activity across all five dimensions.
After all wallets are scored and sorted by composite score (descending), tiers are assigned based on percentile rank:
| Tier | Percentile | Cutoff | Description |
|---|---|---|---|
| Diamond | Top 1% | rank/total <= 0.01 | Elite traders, highest activity across all dimensions |
| Platinum | Top 5% | rank/total <= 0.05 | Very active, diversified participation |
| Gold | Top 15% | rank/total <= 0.15 | Consistent traders with good engagement |
| Silver | Top 40% | rank/total <= 0.40 | Regular participants with moderate activity |
| Bronze | Bottom 60% | everyone else | Casual users, new wallets, or limited activity |
// Tier assignment logic
pct = rank / total
if (pct <= 0.01) tier = "diamond"
else if (pct <= 0.05) tier = "platinum"
else if (pct <= 0.15) tier = "gold"
else if (pct <= 0.40) tier = "silver"
else tier = "bronze"
The scoring formula is backed by 20 deterministic unit tests organized into three test suites:
Composite Scoring (7 tests)
Tier Assignment (8 tests)
Weight Balance (5 tests)
Tests are located at __tests__/scoring.test.ts and can be run with pnpm test.
The scoring system is designed to be fully transparent and reproducible:
lib/types/scoring.ts and exposed in every API response./api/v2/wallet/[address]/score endpoint returns all five normalized components alongside the raw values.version field (currently "v2.1") so changes to the formula are traceable.