Skip to content

Commit beaad72

Browse files
pietro-maximoffgrinry
authored andcommitted
Fix Protocol Data (#1121)
* SOV-5233: update rsk tvl * chore: update tvl bob rsk * chore: cleaunp * Create smart-countries-grow.md
1 parent ecc3830 commit beaad72

File tree

7 files changed

+362
-81
lines changed

7 files changed

+362
-81
lines changed

.changeset/smart-countries-grow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"frontend": patch
3+
---
4+
5+
Fix Protocol Data

apps/frontend/src/app/5_pages/LandingPage/components/ProtocolData/ProtocolData.tsx

Lines changed: 193 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,58 +8,163 @@ import { Accordion, Button, ButtonStyle } from '@sovryn/ui';
88
import { BOB_CHAIN_ID, RSK_CHAIN_ID } from '../../../../../config/chains';
99

1010
import { AmountRenderer } from '../../../../2_molecules/AmountRenderer/AmountRenderer';
11-
import { NativeTokenAmount } from '../../../../2_molecules/NativeTokenAmount/NativeTokenAmount';
12-
import { USD } from '../../../../../constants/currencies';
11+
import {
12+
BITCOIN,
13+
BTC_RENDER_PRECISION,
14+
USD,
15+
} from '../../../../../constants/currencies';
1316
import { translations } from '../../../../../locales/i18n';
1417
import { decimalic } from '../../../../../utils/math';
1518
import { USD_VALUE_PRECISION } from './ProtocolData.constants';
1619
import styles from './ProtocolData.module.css';
20+
import { pickBtcUsd, safeBucketUsd, sanitizeUsd } from './ProtocolData.utils';
1721
import { useGetBOBVolume } from './hooks/useGetBOBVolume';
1822
import { useGetLockedData } from './hooks/useGetLockedData';
1923
import { useGetRSKVolume } from './hooks/useGetRSKVolume';
24+
import { useGetTokens } from './hooks/useGetTokens';
2025

2126
const pageTranslations = translations.landingPage.protocolDataSection;
2227

2328
export const ProtocolData: FC = () => {
24-
const lockedData = useGetLockedData(RSK_CHAIN_ID);
25-
const rskVolume = useGetRSKVolume();
29+
// RSK data (TVL parts + 24h volume)
30+
const rskLocked = useGetLockedData(RSK_CHAIN_ID);
2631

27-
const bobLockedData = useGetLockedData(BOB_CHAIN_ID);
28-
const bobVolume = useGetBOBVolume();
32+
const rskVolumeRaw = useGetRSKVolume(); // 24h USD (string)
33+
34+
// BOB data (TVL aggregate + 24h volume)
35+
const bobLocked = useGetLockedData(BOB_CHAIN_ID);
36+
37+
const bobVolumeRaw = useGetBOBVolume(); // 24h USD (string)
38+
39+
// Tokens for BTC price sourcing
40+
const { value: rskTokens } = useGetTokens(RSK_CHAIN_ID);
41+
const { value: bobTokens } = useGetTokens(BOB_CHAIN_ID);
2942

3043
const navigate = useNavigate();
3144
const [open, toggle] = useReducer(v => !v, false);
32-
3345
const handleClick = useCallback(() => navigate('/stats'), [navigate]);
3446

35-
const rskTVL = useMemo(
47+
// Prefer RSK RBTC/WRBTC for stability; fallback to BOB BTC wrappers.
48+
const rskBtcUsd = useMemo(
49+
() => pickBtcUsd(rskTokens, ['RBTC', 'WRBTC', 'BTC']) ?? 0,
50+
[rskTokens],
51+
);
52+
const bobBtcUsd = useMemo(
3653
() =>
37-
decimalic(lockedData.tvlAmm?.totalUsd || '0')
38-
.add(lockedData.tvlLending?.totalUsd || '0')
39-
.add(lockedData.tvlMynt?.totalUsd || '0')
40-
.add(lockedData.tvlProtocol?.totalUsd || '0')
41-
.add(lockedData.tvlStaking?.totalUsd || '0')
42-
.add(lockedData.tvlSubprotocols?.totalUsd || '0')
43-
.add(lockedData.tvlZero?.totalUsd || '0')
44-
.toString(),
45-
[
46-
lockedData.tvlAmm?.totalUsd,
47-
lockedData.tvlLending?.totalUsd,
48-
lockedData.tvlMynt?.totalUsd,
49-
lockedData.tvlProtocol?.totalUsd,
50-
lockedData.tvlStaking?.totalUsd,
51-
lockedData.tvlSubprotocols?.totalUsd,
52-
lockedData.tvlZero?.totalUsd,
53-
],
54+
pickBtcUsd(bobTokens, [
55+
'WBTC',
56+
'tBTC',
57+
'UniBTC',
58+
'XSOLVBTC',
59+
'SolvBTC',
60+
'BTC',
61+
]) ?? 0,
62+
[bobTokens],
63+
);
64+
65+
// Use ONE global BTC/USD for totals (avoid double-scaling differences).
66+
const globalBtcUsd = useMemo(
67+
() => rskBtcUsd || bobBtcUsd || 0,
68+
[rskBtcUsd, bobBtcUsd],
69+
);
70+
71+
const rskTvlUsd = useMemo(() => {
72+
if (!rskLocked) {
73+
return '0';
74+
}
75+
76+
// Aggregate from buckets, applying numeric caps per bucket
77+
const fromBuckets = decimalic(0)
78+
.add(safeBucketUsd(rskLocked.tvlAmm))
79+
.add(safeBucketUsd(rskLocked.tvlLending))
80+
.add(safeBucketUsd(rskLocked.tvlMynt))
81+
.add(safeBucketUsd(rskLocked.tvlProtocol))
82+
.add(safeBucketUsd(rskLocked.tvlStaking))
83+
.add(safeBucketUsd(rskLocked.tvlSubprotocols))
84+
.add(safeBucketUsd(rskLocked.tvlZero));
85+
86+
//sanity-check against raw total_usd/totalUsd from backend
87+
const rawTotal = Number(
88+
(rskLocked as any)?.total_usd ?? (rskLocked as any)?.totalUsd ?? 0,
89+
);
90+
const safeRawTotal =
91+
!isFinite(rawTotal) || rawTotal < 0 || rawTotal > 1e9 ? 0 : rawTotal;
92+
93+
if (safeRawTotal > 0) {
94+
const diff = Math.abs(fromBuckets.toNumber() - safeRawTotal);
95+
const relDiff = diff / safeRawTotal;
96+
97+
// Log if discrepancy > ~3% (indexer vs graph-wrapper)
98+
if (relDiff > 0.03) {
99+
// eslint-disable-next-line no-console
100+
console.warn('[ProtocolData] RSK TVL mismatch', {
101+
buckets: fromBuckets.toString(),
102+
total_usd: safeRawTotal.toString(),
103+
relDiff,
104+
});
105+
}
106+
}
107+
108+
return fromBuckets.toString();
109+
}, [rskLocked]);
110+
111+
const bobTvlUsd = useMemo(() => {
112+
if (!bobLocked) {
113+
return '0';
114+
}
115+
116+
const raw =
117+
(bobLocked as any)?.total_usd ?? (bobLocked as any)?.totalUsd ?? 0;
118+
119+
return sanitizeUsd(raw, 1e9);
120+
}, [bobLocked]);
121+
122+
const rskTvlBtc = useMemo(
123+
() => (rskBtcUsd ? decimalic(rskTvlUsd).div(rskBtcUsd).toString() : '0'),
124+
[rskTvlUsd, rskBtcUsd],
125+
);
126+
const bobTvlBtc = useMemo(
127+
() => (bobBtcUsd ? decimalic(bobTvlUsd).div(bobBtcUsd).toString() : '0'),
128+
[bobTvlUsd, bobBtcUsd],
129+
);
130+
131+
const rskVolumeUsd = useMemo(
132+
() => sanitizeUsd(rskVolumeRaw, 1e12),
133+
[rskVolumeRaw],
134+
);
135+
const bobVolumeUsd = useMemo(
136+
() => sanitizeUsd(bobVolumeRaw, 1e12),
137+
[bobVolumeRaw],
138+
);
139+
140+
const rskVolumeBtc = useMemo(
141+
() => (rskBtcUsd ? decimalic(rskVolumeUsd).div(rskBtcUsd).toString() : '0'),
142+
[rskVolumeUsd, rskBtcUsd],
143+
);
144+
const bobVolumeBtc = useMemo(
145+
() => (bobBtcUsd ? decimalic(bobVolumeUsd).div(bobBtcUsd).toString() : '0'),
146+
[bobVolumeUsd, bobBtcUsd],
147+
);
148+
149+
const totalTvlUsd = useMemo(
150+
() => decimalic(rskTvlUsd).add(bobTvlUsd).toString(),
151+
[rskTvlUsd, bobTvlUsd],
152+
);
153+
const totalVolUsd = useMemo(
154+
() => decimalic(rskVolumeUsd).add(bobVolumeUsd).toString(),
155+
[rskVolumeUsd, bobVolumeUsd],
54156
);
55157

56-
const total = useMemo(() => {
57-
return {
58-
lockedData:
59-
Number(rskTVL || '0') + Number(bobLockedData.total_usd || '0'),
60-
volumeData: Number(rskVolume || '0') + Number(bobVolume || '0'),
61-
};
62-
}, [bobLockedData.total_usd, bobVolume, rskTVL, rskVolume]);
158+
const totalTvlBtc = useMemo(
159+
() =>
160+
globalBtcUsd ? decimalic(totalTvlUsd).div(globalBtcUsd).toString() : '0',
161+
[totalTvlUsd, globalBtcUsd],
162+
);
163+
const totalVolBtc = useMemo(
164+
() =>
165+
globalBtcUsd ? decimalic(totalVolUsd).div(globalBtcUsd).toString() : '0',
166+
[totalVolUsd, globalBtcUsd],
167+
);
63168

64169
return (
65170
<div>
@@ -79,41 +184,50 @@ export const ProtocolData: FC = () => {
79184
<Accordion
80185
label={
81186
<div className="flex justify-between font-medium w-full">
187+
{/* TOTAL TVL (All Networks) — BTC + USD (one BTC/USD) */}
82188
<div className="flex flex-col items-start sm:min-w-44">
83189
<div className="text-xs text-gray-30 mb-2">
84190
{t(pageTranslations.totalValueLockedAllNetworks)}
85191
</div>
192+
193+
{/* BTC total */}
86194
<div className="sm:text-xl text-gray-10 text-sm sm:font-medium font-semibold leading-8">
87-
<NativeTokenAmount
88-
chainId={RSK_CHAIN_ID}
89-
usdValue={total.lockedData}
90-
precision={4}
195+
<AmountRenderer
196+
value={totalTvlBtc}
197+
suffix={BITCOIN}
198+
precision={BTC_RENDER_PRECISION}
91199
/>
92200
</div>
93201

202+
{/* USD total */}
94203
<div className="text-gray-50 text-sm">
95204
<AmountRenderer
96-
value={total.lockedData}
205+
value={totalTvlUsd}
97206
suffix={USD}
98207
precision={USD_VALUE_PRECISION}
99208
/>
100209
</div>
101210
</div>
102211

212+
{/* TOTAL 24H VOLUME (All Networks) — BTC + USD (one BTC/USD) */}
103213
<div className="ml-10 mr-5 flex flex-col items-start sm:min-w-44">
104214
<div className="text-xs text-gray-30 mb-2">
105215
{t(pageTranslations.volumeAllNetworks)}
106216
</div>
107-
<div className="sm:text-2xl text-gray-10 text-sm sm:font-medium font-semibold leading-8">
108-
<NativeTokenAmount
109-
chainId={RSK_CHAIN_ID}
110-
usdValue={total.volumeData}
217+
218+
{/* 24h volume in BTC */}
219+
<div className="sm:text-xl text-gray-10 text-sm sm:font-medium font-semibold leading-8">
220+
<AmountRenderer
221+
value={totalVolBtc}
222+
suffix={BITCOIN}
223+
precision={BTC_RENDER_PRECISION}
111224
/>
112225
</div>
113226

227+
{/* 24h volume in USD */}
114228
<div className="text-gray-50 text-sm">
115229
<AmountRenderer
116-
value={total.volumeData}
230+
value={totalVolUsd}
117231
suffix={USD}
118232
precision={USD_VALUE_PRECISION}
119233
/>
@@ -123,18 +237,26 @@ export const ProtocolData: FC = () => {
123237
}
124238
children={
125239
<div className="lg:p-4 px-0 py-4 font-medium">
240+
{/* RSK ROW */}
126241
<div className="flex justify-between w-full">
127242
<div className="flex flex-col items-start sm:min-w-44">
128243
<div className="text-xs text-gray-30 mb-2">
129244
{t(pageTranslations.tvlRskNetwork)}
130245
</div>
246+
247+
{/* TVL (RSK) in BTC */}
131248
<div className="text-gray-10 text-sm sm:font-medium font-semibold">
132-
<NativeTokenAmount chainId={RSK_CHAIN_ID} usdValue={rskTVL} />
249+
<AmountRenderer
250+
value={rskTvlBtc}
251+
suffix={BITCOIN}
252+
precision={BTC_RENDER_PRECISION}
253+
/>
133254
</div>
134255

256+
{/* TVL (RSK) in USD */}
135257
<div className="text-gray-50 text-sm">
136258
<AmountRenderer
137-
value={rskTVL}
259+
value={rskTvlUsd}
138260
suffix={USD}
139261
precision={USD_VALUE_PRECISION}
140262
/>
@@ -145,37 +267,47 @@ export const ProtocolData: FC = () => {
145267
<div className="text-xs text-gray-30 mb-2">
146268
{t(pageTranslations.volumeRskNetwork)}
147269
</div>
270+
271+
{/* 24h Volume (RSK) in BTC */}
148272
<div className="text-gray-10 text-sm sm:font-medium font-semibold">
149-
<NativeTokenAmount
150-
chainId={RSK_CHAIN_ID}
151-
usdValue={rskVolume}
273+
<AmountRenderer
274+
value={rskVolumeBtc}
275+
suffix={BITCOIN}
276+
precision={BTC_RENDER_PRECISION}
152277
/>
153278
</div>
154279

280+
{/* 24h Volume (RSK) in USD */}
155281
<div className="text-gray-50 text-sm">
156282
<AmountRenderer
157-
value={rskVolume}
283+
value={rskVolumeUsd}
158284
suffix={USD}
159285
precision={USD_VALUE_PRECISION}
160286
/>
161287
</div>
162288
</div>
163289
</div>
164290

291+
{/* BOB ROW */}
165292
<div className="flex justify-between w-full mt-4">
166293
<div className="flex flex-col sm:min-w-44">
167294
<div className="text-xs text-gray-30 mb-2">
168295
{t(pageTranslations.tvlBobNetwork)}
169296
</div>
170-
<div className="text-gray-10 text-sm">
171-
<NativeTokenAmount
172-
chainId={RSK_CHAIN_ID}
173-
usdValue={bobLockedData.total_usd}
297+
298+
{/* TVL (BOB) in BTC */}
299+
<div className="text-gray-10 text-sm sm:font-medium font-semibold">
300+
<AmountRenderer
301+
value={bobTvlBtc}
302+
suffix={BITCOIN}
303+
precision={BTC_RENDER_PRECISION}
174304
/>
175305
</div>
306+
307+
{/* TVL (BOB) in USD */}
176308
<div className="text-gray-50 text-sm">
177309
<AmountRenderer
178-
value={bobLockedData.total_usd}
310+
value={bobTvlUsd}
179311
suffix={USD}
180312
precision={USD_VALUE_PRECISION}
181313
/>
@@ -186,16 +318,20 @@ export const ProtocolData: FC = () => {
186318
<div className="text-xs text-gray-30 mb-2">
187319
{t(pageTranslations.volumeBobNetwork)}
188320
</div>
321+
322+
{/* 24h Volume (BOB) in BTC */}
189323
<div className="text-gray-10 text-sm sm:font-medium font-semibold">
190-
<NativeTokenAmount
191-
chainId={RSK_CHAIN_ID}
192-
usdValue={bobVolume}
324+
<AmountRenderer
325+
value={bobVolumeBtc}
326+
suffix={BITCOIN}
327+
precision={BTC_RENDER_PRECISION}
193328
/>
194329
</div>
195330

331+
{/* 24h Volume (BOB) in USD */}
196332
<div className="text-gray-50 text-sm">
197333
<AmountRenderer
198-
value={bobVolume}
334+
value={bobVolumeUsd}
199335
suffix={USD}
200336
precision={USD_VALUE_PRECISION}
201337
/>

0 commit comments

Comments
 (0)