Skip to content

Commit

Permalink
feat(tangle-dapp): Compute Restaking TVL Values (#2535)
Browse files Browse the repository at this point in the history
  • Loading branch information
AtelyPham authored Sep 5, 2024
1 parent 9ecab86 commit c799882
Show file tree
Hide file tree
Showing 31 changed files with 715 additions and 173 deletions.
1 change: 1 addition & 0 deletions .lycheeignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ https://github.com/webb-tools/webb-dapp/releases/tag/v1.0.10
https://github.com/webb-tools/webb-dapp/releases/tag/v1.0.11
https://github.com/webb-tools/webb-dapp/releases/tag/v1.0.12
https://github.com/webb-tools/webb-dapp/releases/tag/v1.0.13
https://stats.tangle.tools
# Something happened with conventional commits link, temporary disabled to fix the CI
https://www.conventionalcommits.org/en/v1.0.0/

Expand Down
14 changes: 7 additions & 7 deletions apps/bridge-dapp/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Relayer filter by environment: https://github.com/webb-tools/webb-dapp/commit/5c2ef97cd7e7788b858c414f4b9546bdcfcfc2d8
- Relayer fee and refund support: https://github.com/webb-tools/webb-dapp/commit/32ac5b0c7494c7ca746c6e56bda65cbfd692118f
- Added liquidity check on withdrawal: https://github.com/webb-tools/webb-dapp/commit/f9617e364f40b577f0a5bd4d9dc2bc2cea9f3168
- Added failed transaction monitoring: https://github.com/webb-tools/webb-dapp/commit/f9617e364f40b577f0a5bd4d9dc2bc2cea9f3168
- Added max fee calculation: https://github.com/webb-tools/webb-dapp/commit/6f3fa726513accda142dac87b03e2a06e7d094c3
- Relayer filter by environment
- Relayer fee and refund support
- Added liquidity check on withdrawal
- Added failed transaction monitoring
- Added max fee calculation

### Changed

- Updated confirmation cards UI: https://github.com/webb-tools/webb-dapp/commit/094b85dbc469f1c8b2250e8030b9b02dcb30d9b1
- Updated confirmation cards UI

### Fixed

- Fixed balance calculation: https://github.com/webb-tools/webb-dapp/commit/dece224d7fa739a7b9a02ee3397c9591330e9e9b
- Fixed balance calculation

## [0.0.3] - 2023-04-25

Expand Down
6 changes: 5 additions & 1 deletion apps/tangle-dapp/app/blueprints/[name]/OperatorsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ const OperatorsTable: FC = () => {
restakersCount: o.restakersCount,
concentrationPercentage: o.concentration,
tvlInUsd: o.liquidity.usdValue,
vaultTokens: o.vaults,
vaultTokens: o.vaults.map((v) => ({
name: v,
symbol: v,
amount: 0,
})),
}))}
/>
</div>
Expand Down
12 changes: 1 addition & 11 deletions apps/tangle-dapp/app/blueprints/[name]/VaultAssetsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,7 @@ const VaultAssetsTable: FC<VaultAssetsTableProps> = ({
}) => {
const data = useVaultAssets(LSTTokenIcon);

return (
<VaultAssetsTableUI
isShown={isShown}
data={data.map((d) => ({
id: d.id,
selfStake: d.myStake,
symbol: d.symbol,
tvl: d.tvl,
}))}
/>
);
return <VaultAssetsTableUI isShown={isShown} data={data} />;
};

export default VaultAssetsTable;
6 changes: 3 additions & 3 deletions apps/tangle-dapp/app/blueprints/[name]/useOperators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { LiquidStakingToken } from '../../../types/liquidStaking';
export default function useOperators(): Operator[] {
return [
{
address: 'tgDRbUxr3dV3j5pCW7DrpmswiABCMTN2NxioeDfA9TXLw6X1u',
address: 'tgC2pxrFu34VuBNGsz3yes6PYnE8cf6VQ5JroY96NTUW5cmU2',
identityName: 'PIKACHU.COM',
restakersCount: 43,
concentration: 50.123,
Expand All @@ -21,7 +21,7 @@ export default function useOperators(): Operator[] {
],
},
{
address: 'tgDRbUxr3dV3j5pCW7DrpmswiABCMTN2NxioeDfA9TXLw6X1u',
address: 'tgCFwkpaXGNNfaFQ4dKDCrGkARQztJp82ekxwRJav9MhMiqD1',
identityName: 'CHARIZARD.COM',
restakersCount: 24,
concentration: 60.89,
Expand Down Expand Up @@ -52,7 +52,7 @@ export default function useOperators(): Operator[] {
],
},
{
address: 'tgDRbUxr3dV3j5pCW7DrpmswiABCMTN2NxioeDfA9TXLw6X1u',
address: 'tgCZuFEMk6yFqTzjSs9sZrdSHAWUXRuneA2e1TRxE8GcLQyfS',
identityName: 'GENGAR.COM',
restakersCount: 12,
concentration: 55,
Expand Down
15 changes: 10 additions & 5 deletions apps/tangle-dapp/app/blueprints/[name]/useVaultAssets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,37 @@ export default function useVaultAssets(_: string) {
{
id: '31234',
symbol: 'tgDOT_A',
decimals: 18,
tvl: 5588.23,
myStake: 10.12,
selfStake: BigInt('1012000000000000000000'),
},
{
id: '31235',
symbol: 'tgDOT_B',
decimals: 18,
tvl: 2044.12,
myStake: 0,
selfStake: BigInt(0),
},
{
id: '31236',
symbol: 'tgDOT_C',
decimals: 18,
tvl: 123.12,
myStake: 16,
selfStake: BigInt('16000000000000000000'),
},
{
id: '31237',
symbol: 'tgDOT_D',
decimals: 18,
tvl: 6938.87,
myStake: 100,
selfStake: BigInt('100000000000000000000'),
},
{
id: '31238',
symbol: 'tgDOT_E',
decimals: 18,
tvl: 0,
myStake: 0,
selfStake: BigInt(0),
},
];
}
56 changes: 40 additions & 16 deletions apps/tangle-dapp/app/restake/OperatorsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,31 @@

import { Search } from '@webb-tools/icons/Search';
import { Input } from '@webb-tools/webb-ui-components/components/Input';
import { ComponentProps, useMemo, useState } from 'react';
import { type ComponentProps, type FC, useMemo, useState } from 'react';
import { formatUnits } from 'viem';

import OperatorsTableUI from '../../components/tables/Operators';
import { useRestakeContext } from '../../context/RestakeContext';
import useRestakeOperatorMap from '../../data/restake/useRestakeOperatorMap';
import useIdentities from '../../data/useIdentities';
import type { OperatorMap } from '../../types/restake';

type OperatorUI = NonNullable<
ComponentProps<typeof OperatorsTableUI>['data']
>[number];

const OperatorsTable = () => {
type Props = {
operatorConcentration?: Record<string, number | null>;
operatorMap: OperatorMap;
operatorTVL?: Record<string, number>;
};

const OperatorsTable: FC<Props> = ({
operatorConcentration,
operatorMap,
operatorTVL,
}) => {
const [globalFilter, setGlobalFilter] = useState('');

const { operatorMap } = useRestakeOperatorMap();
const { assetMap } = useRestakeContext();

const { result: identities } = useIdentities(
Expand All @@ -26,24 +36,38 @@ const OperatorsTable = () => {
const operators = useMemo(
() =>
Object.entries(operatorMap).map<OperatorUI>(
([address, { delegationCount, delegations }]) => {
const vaultTokens = delegations
.map((delegation) => assetMap[delegation.assetId]?.symbol)
.filter(Boolean);
([address, { delegations }]) => {
const vaultAssets = delegations
.map((delegation) => ({
asset: assetMap[delegation.assetId],
amount: delegation.amount,
}))
.filter((vaultAsset) => Boolean(vaultAsset.asset));

const restakerSet = delegations.reduce((restakerSet, delegation) => {
restakerSet.add(delegation.delegatorAccountId);
return restakerSet;
}, new Set<string>());

const tvlInUsd = operatorTVL?.[address] ?? null;
const concentrationPercentage =
operatorConcentration?.[address] ?? null;

return {
address,
// TODO: Calculate concentration percentage
concentrationPercentage: 0,
concentrationPercentage,
identityName: identities[address]?.name ?? '',
restakersCount: delegationCount,
// TODO: Calculate tvl in USD
tvlInUsd: 0,
vaultTokens,
restakersCount: restakerSet.size,
tvlInUsd,
vaultTokens: vaultAssets.map(({ asset, amount }) => ({
amount: +formatUnits(amount, asset.decimals),
name: asset.name,
symbol: asset.symbol,
})),
};
},
),
[assetMap, identities, operatorMap],
[assetMap, identities, operatorConcentration, operatorMap, operatorTVL],
);

return (
Expand All @@ -52,7 +76,7 @@ const OperatorsTable = () => {
id="search-validators"
rightIcon={<Search className="mr-2" />}
placeholder="Search identity or address"
className="w-1/3 mb-4 ml-auto -mt-[54px]"
className="w-1/3 mb-1.5 ml-auto -mt-[54px]"
isControlled
debounceTime={500}
value={globalFilter}
Expand Down
87 changes: 67 additions & 20 deletions apps/tangle-dapp/app/restake/TableTabs.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
'use client';

import { ZERO_BIG_INT } from '@webb-tools/dapp-config/constants';
import { TableAndChartTabs } from '@webb-tools/webb-ui-components/components/TableAndChartTabs';
import { TabContent } from '@webb-tools/webb-ui-components/components/Tabs/TabContent';
import { type ComponentProps, useMemo } from 'react';
import { type ComponentProps, type FC, useMemo } from 'react';

import VaultAssetsTable from '../../components/tables/VaultAssets';
import VaultsTable from '../../components/tables/Vaults';
import { useRestakeContext } from '../../context/RestakeContext';
import useRestakeRewardConfig from '../../data/restake/useRestakeRewardConfig';
import type { DelegatorInfo, OperatorMap } from '../../types/restake';
import OperatorsTable from './OperatorsTable';

const RESTAKE_VAULTS_TAB = 'Restake Vaults';
Expand All @@ -19,9 +22,27 @@ type VaultAssetUI = NonNullable<
ComponentProps<typeof VaultAssetsTable>['data']
>[number];

const TableTabs = () => {
type Props = {
delegatorInfo: DelegatorInfo | null;
delegatorTVL?: Record<string, number>;
operatorConcentration?: Record<string, number | null>;
operatorMap: OperatorMap;
operatorTVL?: Record<string, number>;
vaultTVL?: Record<string, number>;
};

const TableTabs: FC<Props> = ({
delegatorInfo,
delegatorTVL,
operatorConcentration,
operatorMap,
operatorTVL,
vaultTVL,
}) => {
const { assetMap } = useRestakeContext();

const { rewardConfig } = useRestakeRewardConfig();

// Recalculate vaults (pools) data from assetMap
const vaults = useMemo(() => {
const vaults: Record<string, VaultUI> = {};
Expand All @@ -30,25 +51,44 @@ const TableTabs = () => {
if (poolId === null) continue;

if (vaults[poolId] === undefined) {
const apyPercentage = rewardConfig.configs[poolId]?.apy ?? null;
const tvlInUsd = vaultTVL?.[poolId] ?? null;

vaults[poolId] = {
id: poolId,
// TODO: Calculate APY
apyPercentage: 0,
apyPercentage,
// TODO: Find out a proper way to get the pool name, now it's the first token name
name: name,
// TODO: Find out a proper way to get the pool symbol, now it's the first token symbol
representToken: symbol,
tokensCount: 1,
// TODO: Calculate tvl in USD
tvlInUsd: 0,
tvlInUsd,
};
} else {
vaults[poolId].tokensCount += 1;
}
}

return vaults;
}, [assetMap]);
}, [assetMap, rewardConfig.configs, vaultTVL]);

const delegatorTotalRestakedAssets = useMemo(() => {
if (!delegatorInfo?.delegations) {
return {};
}

return delegatorInfo.delegations.reduce<Record<string, bigint>>(
(acc, { amountBonded, assetId }) => {
if (acc[assetId] === undefined) {
acc[assetId] = amountBonded;
} else {
acc[assetId] += amountBonded;
}
return acc;
},
{},
);
}, [delegatorInfo?.delegations]);

const tableProps = useMemo<ComponentProps<typeof VaultsTable>['tableProps']>(
() => ({
Expand All @@ -60,17 +100,20 @@ const TableTabs = () => {
const poolId = row.original.id;
const vaultAssets = Object.values(assetMap)
.filter((asset) => asset.poolId === poolId)
.map(
(asset) =>
({
id: asset.id,
symbol: asset.symbol,
// TODO: Calculate tvl
tvl: 0,
// TODO: Calculate self stake
selfStake: 0,
}) satisfies VaultAssetUI,
);
.map((asset) => {
const selfStake =
delegatorTotalRestakedAssets[asset.id] ?? ZERO_BIG_INT;

const tvl = delegatorTVL?.[asset.id] ?? null;

return {
id: asset.id,
symbol: asset.symbol,
decimals: asset.decimals,
tvl,
selfStake,
} satisfies VaultAssetUI;
});

return (
<div className="px-3 pt-4 pb-3 -mx-px bg-mono-0 dark:bg-mono-190 -mt-7 rounded-b-xl">
Expand All @@ -82,7 +125,7 @@ const TableTabs = () => {
);
},
}),
[assetMap],
[assetMap, delegatorTVL, delegatorTotalRestakedAssets],
);

return (
Expand All @@ -95,7 +138,11 @@ const TableTabs = () => {
</TabContent>

<TabContent value={OPERATORS_TAB}>
<OperatorsTable />
<OperatorsTable
operatorConcentration={operatorConcentration}
operatorMap={operatorMap}
operatorTVL={operatorTVL}
/>
</TabContent>
</TableAndChartTabs>
);
Expand Down
Loading

0 comments on commit c799882

Please sign in to comment.