Skip to content

Commit 1059eac

Browse files
authored
Merge pull request #29 from Xeonus/tvl-fixes
chore: data filtering for v2 exploit
2 parents e10ad50 + 4e34c30 commit 1059eac

File tree

7 files changed

+344
-85
lines changed

7 files changed

+344
-85
lines changed

src/data/balancer/useAggregatedProtocolData.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
import { ProtocolData } from './useProtocolDataWithClientOverride';
2828
import { getUnixTimestamp1000DaysAgo } from "../../utils/date";
2929
import {BalancerChartDataItem} from "./balancerTypes";
30+
import { sanitizeChartData, sanitizeScalarValue } from '../../utils/dataValidation';
3031

3132
export interface AggregatedProtocolData {
3233
mainnetData: ProtocolData,
@@ -98,24 +99,24 @@ export default function useAggregatedProtocolData(): AggregatedProtocolData {
9899
useBalancerChainProtocolData(FraxtalNetworkInfo.clientUri, startDate, fraxtalBlockClient, fraxtalClient),
99100
];
100101

101-
// Aggregate numeric metrics
102-
const volume = aggregateNumericMetrics(protocolsData, 'volume24');
103-
const volumeChange = aggregateNumericMetrics(protocolsData, 'volumeChange');
104-
const fees24 = aggregateNumericMetrics(protocolsData, 'fees24');
105-
const protocolFees24 = aggregateNumericMetrics(protocolsData, 'protocolFees24');
106-
const feesChange = aggregateNumericMetrics(protocolsData, 'feesChange');
107-
const protocolFeesChange = aggregateNumericMetrics(protocolsData, 'protocolFeesChange');
108-
const tvl = aggregateNumericMetrics(protocolsData, 'tvl');
109-
const tvlChange = aggregateNumericMetrics(protocolsData, 'tvlChange');
110-
const swaps24 = aggregateNumericMetrics(protocolsData, 'swaps24');
111-
const swapsChange = aggregateNumericMetrics(protocolsData, 'swapsChange');
102+
// Aggregate numeric metrics and sanitize (hack data corruption fix)
103+
const volume = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'volume24'), 0, 'volume');
104+
const volumeChange = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'volumeChange'), 0);
105+
const fees24 = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'fees24'), 0, 'fees');
106+
const protocolFees24 = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'protocolFees24'), 0, 'protocolFees');
107+
const feesChange = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'feesChange'), 0);
108+
const protocolFeesChange = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'protocolFeesChange'), 0);
109+
const tvl = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'tvl'), 0, 'tvl');
110+
const tvlChange = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'tvlChange'), 0);
111+
const swaps24 = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'swaps24'), 0, 'swaps');
112+
const swapsChange = sanitizeScalarValue(aggregateNumericMetrics(protocolsData, 'swapsChange'), 0);
112113

113-
// Aggregate chart data
114-
const overallTvlData = aggregateChartData(protocolsData, 'tvlData');
115-
const overallProtocolFeeData = aggregateChartData(protocolsData, 'protocolFeeData');
116-
const overallVolumeChartData = aggregateChartData(protocolsData, 'volumeData');
117-
const overallFeeChartData = aggregateChartData(protocolsData, 'feeData');
118-
const overallSwapsChartData = aggregateChartData(protocolsData, 'swapData');
114+
// Aggregate chart data and sanitize (hack data corruption fix)
115+
const overallTvlData = sanitizeChartData(aggregateChartData(protocolsData, 'tvlData'), 'tvl');
116+
const overallProtocolFeeData = sanitizeChartData(aggregateChartData(protocolsData, 'protocolFeeData'), 'protocolFees');
117+
const overallVolumeChartData = sanitizeChartData(aggregateChartData(protocolsData, 'volumeData'), 'volume');
118+
const overallFeeChartData = sanitizeChartData(aggregateChartData(protocolsData, 'feeData'), 'fees');
119+
const overallSwapsChartData = sanitizeChartData(aggregateChartData(protocolsData, 'swapData'), 'swaps');
119120

120121
return {
121122
mainnetData: protocolsData[0],

src/data/balancer/useBalancerPoolFeeSnapshotData.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {useBalancerPoolFeeSnapshotsLazyQuery,} from "../../apollo/generated/grap
33
import {ApolloClient, NormalizedCacheObject} from "@apollo/client";
44
import {useEffect, useState} from "react";
55
import {JoinExitTimestamp, PoolFeeSnapshotData} from "./balancerTypes";
6+
import { sanitizeScalarValue } from '../../utils/dataValidation';
67

78
export function useBalancerPoolFeeSnapshotData(clientUri: string, startTimestamp: number, blockClientOverride?: ApolloClient<NormalizedCacheObject>, clientOverride?: ApolloClient<NormalizedCacheObject>): PoolFeeSnapshotData | undefined {
89

@@ -120,13 +121,14 @@ export function getSnapshotFees(feeSnapshotNow: PoolFeeSnapshotData, feeSnapshot
120121
};
121122
}
122123
// Default to 0 if no corresponding past pool is found
123-
const swapFees = nowPool.swapFees - (pastPool?.swapFees || 0);
124-
const totalSwapFee = nowPool.totalSwapFee - (pastPool?.totalSwapFee || 0);
125-
const totalProtocolFee = nowPool.totalProtocolFee - (pastPool?.totalProtocolFee ||0);
126-
const totalProtocolFeePaidInBPT = nowPool.totalProtocolFeePaidInBPT - (pastPool?.totalProtocolFeePaidInBPT || 0);
127-
const liquidity = nowPool.liquidity;
128-
const swapVolume = nowPool.swapVolume - (pastPool?.swapVolume || 0);
129-
const protocolFee = nowPool.protocolFee - (pastPool?.protocolFee || 0)
124+
// Sanitize fee snapshot values (hack data corruption fix)
125+
const swapFees = sanitizeScalarValue(nowPool.swapFees - (pastPool?.swapFees || 0), 0, 'fees');
126+
const totalSwapFee = sanitizeScalarValue(nowPool.totalSwapFee - (pastPool?.totalSwapFee || 0), 0, 'fees');
127+
const totalProtocolFee = sanitizeScalarValue(nowPool.totalProtocolFee - (pastPool?.totalProtocolFee || 0), 0, 'protocolFees');
128+
const totalProtocolFeePaidInBPT = sanitizeScalarValue(nowPool.totalProtocolFeePaidInBPT - (pastPool?.totalProtocolFeePaidInBPT || 0), 0, 'protocolFees');
129+
const liquidity = sanitizeScalarValue(nowPool.liquidity, 0, 'tvl');
130+
const swapVolume = sanitizeScalarValue(nowPool.swapVolume - (pastPool?.swapVolume || 0), 0, 'volume');
131+
const protocolFee = sanitizeScalarValue(nowPool.protocolFee - (pastPool?.protocolFee || 0), 0, 'protocolFees');
130132
const isInRecoveryMode = nowPool.isInRecoveryMode //if the pool is in recovery mode at newest snapshot date, then tag as such
131133
return {
132134
...nowPool, // Copy all current pool data
@@ -141,7 +143,7 @@ export function getSnapshotFees(feeSnapshotNow: PoolFeeSnapshotData, feeSnapshot
141143
// Update other fields as necessary
142144
tokens: nowPool.tokens.map(token => {
143145
const pastToken = pastPool?.tokens.find(p => p.symbol === token.symbol);
144-
const paidProtocolFees = (token.paidProtocolFees ? token.paidProtocolFees : 0) - (pastToken?.paidProtocolFees || 0);
146+
const paidProtocolFees = sanitizeScalarValue((token.paidProtocolFees ? token.paidProtocolFees : 0) - (pastToken?.paidProtocolFees || 0), 0, 'protocolFees');
145147
// Subtract other token-specific fields as necessary
146148
return {
147149
...token,

src/data/balancer/usePools.ts

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { BalancerChartDataItem, PoolData } from './balancerTypes';
1515
import { CoingeckoSnapshotPriceData } from './useTokens';
1616
import { DateTime } from 'luxon';
1717
import {CG_KEY} from "./constants";
18+
import { sanitizeChartData, sanitizeScalarValue } from '../../utils/dataValidation';
1819

1920
function getPoolValues(
2021
poolId: string,
@@ -131,6 +132,21 @@ export function useBalancerPools(first = 250, startunixTime = startTimestamp, en
131132

132133
//TODO: token price information is not stored in PoolData Object model anymore -> remove
133134

135+
// Sanitize pool metrics (hack data corruption fix)
136+
const sanitizedTvl = sanitizeScalarValue(poolData.tvl, 0, 'tvl');
137+
const sanitizedTvl24 = sanitizeScalarValue(poolData24.tvl, 0, 'tvl');
138+
const sanitizedVolume = sanitizeScalarValue(poolData.volume, 0, 'volume');
139+
const sanitizedVolume24 = sanitizeScalarValue(poolData24.volume, 0, 'volume');
140+
const sanitizedFees = sanitizeScalarValue(poolData.fees, 0, 'fees');
141+
const sanitizedFees24 = sanitizeScalarValue(poolData24.fees, 0, 'fees');
142+
const sanitizedFeesEpoch = sanitizeScalarValue(poolData.feesEpoch, 0, 'fees');
143+
const sanitizedProtocolFeesEpoch = sanitizeScalarValue(poolData.protcolFeesEpoch, 0, 'protocolFees');
144+
145+
const volumeDelta = sanitizedVolume - sanitizedVolume24;
146+
const feesDelta = sanitizedFees - sanitizedFees24;
147+
const tvlChange = sanitizedTvl24 !== 0 ? (sanitizedTvl - sanitizedTvl24) / sanitizedTvl24 : 0;
148+
const volumeChange = sanitizedVolume24 !== 0 ? volumeDelta / sanitizedVolume24 : 0;
149+
134150
return {
135151
...pool,
136152
name: pool.name || '',
@@ -152,18 +168,17 @@ export function useBalancerPools(first = 250, startunixTime = startTimestamp, en
152168
balance,
153169
};
154170
}),
155-
liquidity: poolData.tvl,
171+
liquidity: sanitizedTvl,
156172
sqrtPrice: 0,
157173
tick: 0,
158-
volumeUSD: poolData.volume - poolData24.volume,
159-
volumeUSDChange:
160-
(poolData.volume - poolData24.volume) / poolData24.volume,
174+
volumeUSD: sanitizeScalarValue(volumeDelta, 0),
175+
volumeUSDChange: sanitizeScalarValue(volumeChange, 0),
161176
//volumeUSDChange: 100 / poolData24.volume * poolData.volume,
162-
feesUSD: poolData.fees - poolData24.fees,
163-
feesEpochUSD: poolData.feesEpoch,
164-
protocolFeesEpocUSD: poolData.protcolFeesEpoch,
165-
tvlUSD: poolData.tvl,
166-
tvlUSDChange: (poolData.tvl - poolData24.tvl) / poolData24.tvl,
177+
feesUSD: sanitizeScalarValue(feesDelta, 0),
178+
feesEpochUSD: sanitizedFeesEpoch,
179+
protocolFeesEpocUSD: sanitizedProtocolFeesEpoch,
180+
tvlUSD: sanitizedTvl,
181+
tvlUSDChange: sanitizeScalarValue(tvlChange, 0),
167182
//tvlUSDChange: 100 / poolData24.tvl * poolData.tvl,
168183
poolType: poolData.poolType + "",
169184
amp: pool.amp ? pool.amp : '0',
@@ -243,6 +258,19 @@ export function useBalancerPoolSingleData(poolId: string): PoolData | null {
243258
}
244259

245260

261+
// Sanitize pool metrics (hack data corruption fix)
262+
const sanitizedTvl = sanitizeScalarValue(parseFloat(pool.totalLiquidity), 0, 'tvl');
263+
const sanitizedTvl24 = sanitizeScalarValue(parseFloat(pool24.totalLiquidity), 0, 'tvl');
264+
const sanitizedVolume = sanitizeScalarValue(parseFloat(pool.totalSwapVolume), 0, 'volume');
265+
const sanitizedVolume24 = sanitizeScalarValue(parseFloat(pool24.totalSwapVolume), 0, 'volume');
266+
const sanitizedFees = sanitizeScalarValue(parseFloat(pool.totalSwapFee), 0, 'fees');
267+
const sanitizedFees24 = sanitizeScalarValue(parseFloat(pool24.totalSwapFee), 0, 'fees');
268+
269+
const volumeDelta = sanitizedVolume - sanitizedVolume24;
270+
const feesDelta = sanitizedFees - sanitizedFees24;
271+
const tvlChange = sanitizedTvl24 !== 0 ? (sanitizedTvl - sanitizedTvl24) / sanitizedTvl24 : 0;
272+
const volumeChange = sanitizedVolume24 !== 0 ? volumeDelta / sanitizedVolume24 : 0;
273+
246274
return {
247275
...pool,
248276
name: pool.name || '',
@@ -264,18 +292,17 @@ export function useBalancerPoolSingleData(poolId: string): PoolData | null {
264292
balance,
265293
};
266294
}),
267-
liquidity: parseFloat(pool.totalLiquidity),
295+
liquidity: sanitizedTvl,
268296
sqrtPrice: 0,
269297
tick: 0,
270-
volumeUSD: parseFloat(pool.totalSwapVolume) - parseFloat(pool24.totalSwapVolume),
271-
volumeUSDChange:
272-
(parseFloat(pool.totalSwapVolume) - parseFloat(pool24.totalSwapVolume)) / parseFloat(pool24.totalSwapVolume),
298+
volumeUSD: sanitizeScalarValue(volumeDelta, 0),
299+
volumeUSDChange: sanitizeScalarValue(volumeChange, 0),
273300
//volumeUSDChange: 100 / poolData24.volume * poolData.volume,
274-
feesUSD: parseFloat(pool.totalSwapFee) - parseFloat(pool24.totalSwapFee),
301+
feesUSD: sanitizeScalarValue(feesDelta, 0),
275302
feesEpochUSD: 0,
276303
protocolFeesEpocUSD: 0,
277-
tvlUSD: parseFloat(pool.totalLiquidity),
278-
tvlUSDChange: (parseFloat(pool.totalLiquidity) - parseFloat(pool24.totalLiquidity)) / parseFloat(pool24.totalLiquidity),
304+
tvlUSD: sanitizedTvl,
305+
tvlUSDChange: sanitizeScalarValue(tvlChange, 0),
279306
//tvlUSDChange: 100 / poolData24.tvl * poolData.tvl,
280307
poolType: pool.poolType + "",
281308
amp: pool.amp ? pool.amp : '0',
@@ -428,11 +455,12 @@ export function useBalancerPoolPageData(poolId: string): {
428455

429456
const tokenDatas = coingeckoSnapshotData;
430457

458+
// Sanitize chart data (hack data corruption fix)
431459
return {
432-
tvlData,
433-
volumeData,
434-
feesData,
435-
protocolFeesData,
460+
tvlData: sanitizeChartData(tvlData, 'tvl'),
461+
volumeData: sanitizeChartData(volumeData, 'volume'),
462+
feesData: sanitizeChartData(feesData, 'fees'),
463+
protocolFeesData: sanitizeChartData(protocolFeesData, 'protocolFees'),
436464
tokenDatas,
437465
};
438466
}

src/data/balancer/useProtocolData.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useEffect } from 'react';
55
import { unixToDate } from '../../utils/date';
66
import { BalancerChartDataItem } from './balancerTypes';
77
import { useActiveNetworkVersion } from '../../state/application/hooks';
8+
import { sanitizeChartData, sanitizeScalarValue } from '../../utils/dataValidation';
89

910
export interface ProtocolData {
1011
volume24?: number;
@@ -127,22 +128,37 @@ export function useBalancerProtocolData(): ProtocolData {
127128
const swaps24 = parseFloat(balancer24.totalSwapCount);
128129
const swaps48 = parseFloat(balancer48.totalSwapCount)
129130

131+
// Sanitize scalar values (hack data corruption fix)
132+
const sanitizedTvl = sanitizeScalarValue(tvl, 0, 'tvl');
133+
const sanitizedTvl24 = sanitizeScalarValue(tvl24, 0, 'tvl');
134+
const sanitizedVolume24Delta = sanitizeScalarValue(volume - volume24, 0, 'volume');
135+
const sanitizedVolume24 = sanitizeScalarValue(volume24, 0, 'volume');
136+
const sanitizedVolume48 = sanitizeScalarValue(volume48, 0, 'volume');
137+
const sanitizedFees24Delta = sanitizeScalarValue(fees - fees24, 0, 'fees');
138+
const sanitizedProtocolFees24Delta = sanitizeScalarValue(protocolFees - protocolFees24, 0, 'protocolFees');
139+
const sanitizedSwaps24Delta = sanitizeScalarValue(swaps - swaps24, 0, 'swaps');
140+
141+
// Calculate changes with sanitized values
142+
const volume24Delta = sanitizedVolume24 - sanitizedVolume48;
143+
const volumeChangeCalc = volume24Delta !== 0 ? (sanitizedVolume24Delta - volume24Delta) / volume24Delta : 0;
144+
const tvlChangeCalc = sanitizedTvl24 !== 0 ? (sanitizedTvl - sanitizedTvl24) / sanitizedTvl24 : 0;
145+
130146
return {
131-
volume24: volume - volume24,
132-
volumeChange: (volume - volume24 - (volume24 - volume48)) / (volume24 - volume48),
133-
tvl,
134-
tvlChange: (tvl - tvl24) / tvl24,
135-
fees24: fees - fees24,
136-
protocolFees24: protocolFees - protocolFees24,
137-
protocolFeesChange: (protocolFees - protocolFees24 - (protocolFees24 - protocolFees48)) / (protocolFees24 - protocolFees48),
138-
feesChange: (fees - fees24 - (fees24 - fees48)) / (fees24 - fees48),
139-
swaps24: swaps - swaps24,
140-
swapsChange: (swaps - swaps24 - (swaps24 - swaps48)) / (swaps24 - swaps48),
141-
tvlData,
142-
volumeData,
143-
swapData,
144-
feeData,
145-
protocolFeeData,
147+
volume24: sanitizedVolume24Delta,
148+
volumeChange: sanitizeScalarValue(volumeChangeCalc, 0),
149+
tvl: sanitizedTvl,
150+
tvlChange: sanitizeScalarValue(tvlChangeCalc, 0),
151+
fees24: sanitizedFees24Delta,
152+
protocolFees24: sanitizedProtocolFees24Delta,
153+
protocolFeesChange: sanitizeScalarValue((protocolFees - protocolFees24 - (protocolFees24 - protocolFees48)) / (protocolFees24 - protocolFees48), 0),
154+
feesChange: sanitizeScalarValue((fees - fees24 - (fees24 - fees48)) / (fees24 - fees48), 0),
155+
swaps24: sanitizedSwaps24Delta,
156+
swapsChange: sanitizeScalarValue((swaps - swaps24 - (swaps24 - swaps48)) / (swaps24 - swaps48), 0),
157+
tvlData: sanitizeChartData(tvlData, 'tvl'),
158+
volumeData: sanitizeChartData(volumeData, 'volume'),
159+
swapData: sanitizeChartData(swapData, 'swaps'),
160+
feeData: sanitizeChartData(feeData, 'fees'),
161+
protocolFeeData: sanitizeChartData(protocolFeeData, 'protocolFees'),
146162
whaleSwaps: data.whaleSwaps,
147163
};
148164
}

src/data/balancer/useProtocolDataWithClientOverride.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { useEffect } from 'react';
55
import { unixToDate } from '../../utils/date';
66
import { BalancerChartDataItem } from './balancerTypes';
77
import { ApolloClient, NormalizedCacheObject } from '@apollo/client';
8+
import { sanitizeChartData, sanitizeScalarValue } from '../../utils/dataValidation';
89

910
export interface ProtocolData {
1011
volume24?: number;
@@ -126,22 +127,37 @@ export function useBalancerChainProtocolData(clientUri: string, startTimestamp:
126127
const swaps24 = parseFloat(balancer24.totalSwapCount);
127128
const swaps48 = parseFloat(balancer48.totalSwapCount)
128129

130+
// Sanitize scalar values (hack data corruption fix)
131+
const sanitizedTvl = sanitizeScalarValue(tvl, 0, 'tvl');
132+
const sanitizedTvl24 = sanitizeScalarValue(tvl24, 0, 'tvl');
133+
const sanitizedVolume24Delta = sanitizeScalarValue(volume - volume24, 0, 'volume');
134+
const sanitizedVolume24 = sanitizeScalarValue(volume24, 0, 'volume');
135+
const sanitizedVolume48 = sanitizeScalarValue(volume48, 0, 'volume');
136+
const sanitizedFees24Delta = sanitizeScalarValue(fees - fees24, 0, 'fees');
137+
const sanitizedProtocolFees24Delta = sanitizeScalarValue(protocolFees - protocolFees24, 0, 'protocolFees');
138+
const sanitizedSwaps24Delta = sanitizeScalarValue(swaps - swaps24, 0, 'swaps');
139+
140+
// Calculate changes with sanitized values
141+
const volume24Delta = sanitizedVolume24 - sanitizedVolume48;
142+
const volumeChangeCalc = volume24Delta !== 0 ? (sanitizedVolume24Delta - volume24Delta) / volume24Delta : 0;
143+
const tvlChangeCalc = sanitizedTvl24 !== 0 ? (sanitizedTvl - sanitizedTvl24) / sanitizedTvl24 : 0;
144+
129145
return {
130-
volume24: volume - volume24,
131-
volumeChange: (volume - volume24 - (volume24 - volume48)) / (volume24 - volume48),
132-
tvl,
133-
tvlChange: (tvl - tvl24) / tvl24,
134-
fees24: fees - fees24,
135-
protocolFees24: protocolFees - protocolFees24,
136-
protocolFeesChange: (protocolFees - protocolFees24 - (protocolFees24 - protocolFees48)) / (protocolFees24 - protocolFees48),
137-
feesChange: (fees - fees24 - (fees24 - fees48)) / (fees24 - fees48),
138-
swaps24: swaps - swaps24,
139-
swapsChange: (swaps - swaps24 - (swaps24 - swaps48)) / (swaps24 - swaps48),
140-
tvlData,
141-
volumeData,
142-
swapData,
143-
feeData,
144-
protocolFeeData,
146+
volume24: sanitizedVolume24Delta,
147+
volumeChange: sanitizeScalarValue(volumeChangeCalc, 0),
148+
tvl: sanitizedTvl,
149+
tvlChange: sanitizeScalarValue(tvlChangeCalc, 0),
150+
fees24: sanitizedFees24Delta,
151+
protocolFees24: sanitizedProtocolFees24Delta,
152+
protocolFeesChange: sanitizeScalarValue((protocolFees - protocolFees24 - (protocolFees24 - protocolFees48)) / (protocolFees24 - protocolFees48), 0),
153+
feesChange: sanitizeScalarValue((fees - fees24 - (fees24 - fees48)) / (fees24 - fees48), 0),
154+
swaps24: sanitizedSwaps24Delta,
155+
swapsChange: sanitizeScalarValue((swaps - swaps24 - (swaps24 - swaps48)) / (swaps24 - swaps48), 0),
156+
tvlData: sanitizeChartData(tvlData, 'tvl'),
157+
volumeData: sanitizeChartData(volumeData, 'volume'),
158+
swapData: sanitizeChartData(swapData, 'swaps'),
159+
feeData: sanitizeChartData(feeData, 'fees'),
160+
protocolFeeData: sanitizeChartData(protocolFeeData, 'protocolFees'),
145161
whaleSwaps: data.whaleSwaps,
146162
};
147163
}

0 commit comments

Comments
 (0)