Skip to content

Commit ba98761

Browse files
authored
CFG token migration (#2663)
* Add migration page to transfer from eth to eth * Fix some bugs and add design changes * Remove some wording * Add design changes to eth migration * Add feeback * wip: MIGRATION TABLE * Hide banner if balance is undefined // zero or null * Add feedback * WIP - migration table
1 parent 3cfaee1 commit ba98761

34 files changed

Lines changed: 2655 additions & 68 deletions

File tree

centrifuge-app/.env-config/.env.demo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ REACT_APP_TINLAKE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_clhi43
2121
REACT_APP_TREASURY=kAJkmGxAd6iqX9JjWTdhXgCf2PL1TAphTRYrmEqzBrYhwbXAn
2222
REACT_APP_PRIME_IPFS_HASH=QmQfcuHM3EGrtpjhitDwJsgie5THLPtRNzvk7N3uymgHGc
2323
REACT_APP_ONFINALITY_KEY=0e1c049f-d876-4e77-a45f-b5afdf5739b2
24-
REACT_APP_TENDERLY_KEY=18aMTJlpNb1lElcYNkkunC
24+
REACT_APP_TENDERLY_KEY=18aMTJlpNb1lElcYNkkunC

centrifuge-app/.env-config/.env.development

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ REACT_APP_TINLAKE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_clhi43
2121
REACT_APP_TREASURY=kAJkmGxAd6iqX9JjWTdhXgCf2PL1TAphTRYrmEqzBrYhwbXAn
2222
REACT_APP_PRIME_IPFS_HASH=QmQfcuHM3EGrtpjhitDwJsgie5THLPtRNzvk7N3uymgHGc
2323
REACT_APP_ONFINALITY_KEY=0e1c049f-d876-4e77-a45f-b5afdf5739b2
24-
REACT_APP_TENDERLY_KEY=18aMTJlpNb1lElcYNkkunC
24+
REACT_APP_TENDERLY_KEY=18aMTJlpNb1lElcYNkkunC

centrifuge-app/.env-config/.env.production

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@ REACT_APP_TINLAKE_SUBGRAPH_URL=https://api.goldsky.com/api/public/project_clhi43
2121
REACT_APP_TREASURY=4dpEcgqJRyJK3J8Es6v8ZfVntV7c64Ysgcjd4hYwyGoFPWbg
2222
REACT_APP_PRIME_IPFS_HASH=QmfV1mYU6oLJn7HMvCrU3LAKwzW742Y1U7Tads3DnhVahf
2323
REACT_APP_ONFINALITY_KEY=84bb59f4-05cc-440b-8fd4-7917623a90c6
24-
REACT_APP_TENDERLY_KEY=18aMTJlpNb1lElcYNkkunC
24+
REACT_APP_TENDERLY_KEY=18aMTJlpNb1lElcYNkkunC

centrifuge-app/src/components/AssetSummary.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ type Props = {
1212
children?: React.ReactNode
1313
}
1414

15-
export function AssetSummary({ data, children }: Props) {
15+
export function AssetSummary({ data, children, ...props }: Props) {
1616
const theme = useTheme()
1717
return (
1818
<Stack
1919
bg={theme.colors.backgroundSecondary}
2020
border={`1px solid ${theme.colors.borderSecondary}`}
2121
borderRadius={10}
2222
padding={2}
23+
{...props}
2324
>
2425
<Shelf gap={2}>
2526
{data?.map(({ label, value, heading, children }, index) => (

centrifuge-app/src/components/Charts/PoolPerformanceChart.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ function PoolPerformanceChart() {
217217
<CustomLegend selectedTabIndex={selectedTabIndex} data={today} setRange={setRange} />
218218
<Shelf gap={4} width="100%" color="textSecondary" mt={4}>
219219
{chartData?.length ? (
220-
<ResponsiveContainer width="100%" height={260} minHeight={260} maxHeight={260}>
220+
<ResponsiveContainer width="100%" height={280} minHeight={280} maxHeight={280}>
221221
<ComposedChart data={chartData} margin={{ left: -36 }}>
222222
<defs>
223223
<linearGradient id="colorPoolValue" x1="0" y1="0" x2="0" y2="1">
@@ -232,7 +232,7 @@ function PoolPerformanceChart() {
232232
minTickGap={100000}
233233
tickLine={false}
234234
type="category"
235-
tick={(props) => <CustomTick {...props} y={190} />}
235+
tick={(props) => <CustomTick {...props} y={270} />}
236236
ticks={getOneDayPerMonth(chartData, 'day')}
237237
/>
238238
<YAxis

centrifuge-app/src/components/DebugFlags/config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export type Key =
5151
| 'showGmp'
5252
| 'showReports'
5353
| 'showAPYGraph'
54+
| 'showMigrationIndexer'
5455

5556
export const flagsConfig = {
5657
address: {
@@ -146,6 +147,11 @@ export const flagsConfig = {
146147
default: false,
147148
type: 'checkbox',
148149
},
150+
showMigrationIndexer: {
151+
alwaysShow: true,
152+
default: false,
153+
type: 'checkbox',
154+
},
149155
} satisfies Record<Key, DebugFlagConfig>
150156

151157
export const genericFlagsConfig = flagsConfig as Record<string, DebugFlagConfig>

centrifuge-app/src/components/PoolOverview/PoolPerfomance.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import PoolPerformanceChart from '../Charts/PoolPerformanceChart'
44
import { Spinner } from '../Spinner'
55

66
export const PoolPerformance = () => (
7-
<React.Suspense fallback={<Spinner style={{ height: 420 }} />}>
8-
<Card height={420}>
7+
<React.Suspense fallback={<Spinner style={{ height: 480 }} />}>
8+
<Card height={480}>
99
<Stack gap={2}>
1010
<PoolPerformanceChart />
1111
</Stack>

centrifuge-app/src/components/Portfolio/Holdings.tsx

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { useMatch, useNavigate } from 'react-router'
66
import { useLocation } from 'react-router-dom'
77
import { useTheme } from 'styled-components'
88
import { evmChains } from '../../../src/config'
9+
import { useTokenBalance } from '../../../src/pages/Portfolio/useTokenBalance'
10+
import { useAddress } from '../../../src/utils/useAddress'
911
import daiLogo from '../../assets/images/dai-logo.svg'
1012
import ethLogo from '../../assets/images/ethereum.svg'
1113
import centLogo from '../../assets/images/logoCentrifuge.svg'
@@ -41,6 +43,7 @@ export type Holding = {
4143
unrealizedYield?: Rate | null
4244
connectedNetwork?: any
4345
hideCurrencyName?: boolean
46+
showMigration?: boolean
4447
}
4548

4649
const NetworkCell = ({ chainId }: { chainId: Holding['chainId'] }) => {
@@ -60,14 +63,29 @@ const NetworkCell = ({ chainId }: { chainId: Holding['chainId'] }) => {
6063
)
6164
}
6265

66+
const MigrateButtonCell = () => {
67+
const { evm, isEvmOnSubstrate } = useWallet()
68+
const chainId = evm.chainId ?? undefined
69+
const address = useAddress(chainId ? 'evm' : 'substrate')
70+
return (
71+
<RouterLinkButton
72+
to={isEvmAddress(address) && !isEvmOnSubstrate ? 'migrate/eth' : 'migrate/cent'}
73+
small
74+
variant="inverted"
75+
>
76+
Migrate
77+
</RouterLinkButton>
78+
)
79+
}
80+
6381
const columns: Column[] = [
6482
{
6583
align: 'left',
6684
header: 'Token',
6785
cell: (token: Holding) => {
6886
return <TokenWithIcon {...token} />
6987
},
70-
width: '150px',
88+
width: '180px',
7189
},
7290
{
7391
align: 'center',
@@ -138,9 +156,10 @@ const columns: Column[] = [
138156
align: 'right',
139157
header: '', // invest redeem buttons
140158
width: 'max-content',
141-
cell: ({ showActions, poolId, trancheId, currency, connectedNetwork }: Holding) => {
159+
cell: ({ showActions, poolId, trancheId, currency, connectedNetwork, address, showMigration }: Holding) => {
142160
return (
143-
<Grid gap={1} justifySelf="end">
161+
<Grid gap={1} display="flex" alignItems="flex-end">
162+
{showMigration && <MigrateButtonCell address={address} />}
144163
{showActions ? (
145164
trancheId ? (
146165
<Shelf gap={1}>
@@ -221,6 +240,7 @@ export function useHoldings(address?: string, chainId?: number, showActions = tr
221240
const portfolioTokens = usePortfolioTokens(centAddress)
222241
const currencies = usePoolCurrencies()
223242
const CFGPrice = useCFGTokenPrice()
243+
const tokenBalances = useTokenBalance(address)
224244

225245
const tokens: Holding[] = [
226246
...portfolioTokens.map((token) => ({
@@ -259,6 +279,30 @@ export function useHoldings(address?: string, chainId?: number, showActions = tr
259279
connectedNetwork: wallet.connectedNetworkName,
260280
}
261281
}),
282+
tokenBalances.data?.legacy && {
283+
position: Dec(tokenBalances.data?.legacy?.balance || 0),
284+
marketValue: Dec(tokenBalances.data?.legacy?.balance || 0).mul(Dec(CFGPrice ?? 0)),
285+
tokenPrice: Dec(CFGPrice ?? 0),
286+
trancheId: '',
287+
poolId: '',
288+
currency: tokenBalances.data?.legacy?.currency,
289+
showActions: false,
290+
connectedNetwork: chainId,
291+
showMigration: !tokenBalances.data?.legacy?.balance.isZero(),
292+
chainId: 1,
293+
},
294+
tokenBalances.data?.new && {
295+
position: Dec(tokenBalances.data?.new?.balance || 0),
296+
marketValue: Dec(tokenBalances.data?.new?.balance || 0).mul(Dec(CFGPrice ?? 0)),
297+
tokenPrice: Dec(CFGPrice ?? 0),
298+
trancheId: '',
299+
poolId: '',
300+
currency: tokenBalances.data?.new?.currency,
301+
showActions: false,
302+
connectedNetwork: chainId,
303+
showMigration: false,
304+
chainId: 1,
305+
},
262306
...(centBalances?.currencies
263307
?.filter((currency) => currency.balance.gtn(0))
264308
.map((currency) => {
@@ -275,7 +319,8 @@ export function useHoldings(address?: string, chainId?: number, showActions = tr
275319
connectedNetwork: wallet.connectedNetworkName,
276320
}
277321
}) || []),
278-
...((wallet.connectedNetwork === 'centrifuge' && showActions) || centBalances?.native.balance.gtn(0)
322+
...((wallet.connectedNetworkName?.toLowerCase() === 'centrifuge' && showActions) ||
323+
centBalances?.native.balance.gtn(0)
279324
? [
280325
{
281326
currency: {
@@ -286,7 +331,7 @@ export function useHoldings(address?: string, chainId?: number, showActions = tr
286331
key: 'Native',
287332
isPoolCurrency: false,
288333
isPermissioned: false,
289-
displayName: centBalances?.native.currency.symbol ?? 'CFG',
334+
displayName: 'Legacy CFG',
290335
},
291336
poolId: '',
292337
trancheId: '',
@@ -295,6 +340,7 @@ export function useHoldings(address?: string, chainId?: number, showActions = tr
295340
marketValue: CFGPrice ? centBalances?.native.balance.toDecimal().mul(CFGPrice) ?? Dec(0) : Dec(0),
296341
showActions: isPortfolioPage,
297342
connectedNetwork: wallet.connectedNetworkName,
343+
showMigration: !centBalances?.native.balance.isZero(),
298344
},
299345
]
300346
: []),
@@ -369,10 +415,15 @@ export const TokenWithIcon = ({ poolId, currency, hideCurrencyName = false }: Ho
369415
const cent = useCentrifuge()
370416
const { sizes } = useTheme()
371417

418+
const displayEthLogo =
419+
currency?.name?.toLowerCase()?.includes('eth') ||
420+
currency.name.toLowerCase() === 'cfg' ||
421+
currency.symbol.toLowerCase().includes('wcfg')
422+
372423
const getIcon = () => {
373424
if (metadata?.pool?.icon?.uri) {
374425
return cent.metadata.parseMetadataUrl(metadata.pool.icon.uri)
375-
} else if (currency?.name?.toLowerCase()?.includes('eth')) {
426+
} else if (displayEthLogo) {
376427
return ethLogo
377428
} else if (currency?.symbol?.toLowerCase() === 'dai') {
378429
return daiLogo

centrifuge-app/src/components/Root.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ const PoolTransactionsPage = React.lazy(() => import('../pages/PoolTransactions'
7979
const ConvertAddressPage = React.lazy(() => import('../pages/ConvertAddress'))
8080
const PoolsPage = React.lazy(() => import('../pages/Pools'))
8181
const DashboardPage = React.lazy(() => import('../pages/Dashboard'))
82+
const CFGTokenMigrationPage = React.lazy(() => import('../pages/Portfolio/CFGTokenMigration'))
83+
const CFGTokenMigrationCentPage = React.lazy(() => import('../pages/Portfolio/CFGTokenMigrationCent'))
8284

8385
const router = createHashRouter([
8486
{
@@ -118,6 +120,16 @@ const router = createHashRouter([
118120
handle: { component: PoolTransactionsPage },
119121
},
120122
{ path: '/portfolio', element: <PortfolioPage />, handle: { component: PortfolioPage } },
123+
{
124+
path: '/portfolio/migrate/eth',
125+
element: <CFGTokenMigrationPage />,
126+
handle: { component: CFGTokenMigrationPage },
127+
},
128+
{
129+
path: '/portfolio/migrate/cent',
130+
element: <CFGTokenMigrationCentPage />,
131+
handle: { component: CFGTokenMigrationCentPage },
132+
},
121133
{ path: '/prime/:dao', element: <PrimeDetailPage />, handle: { component: PrimeDetailPage } },
122134
{ path: '/prime', element: <PrimePage />, handle: { component: PrimePage } },
123135
{ path: '/disclaimer', element: <InvestmentDisclaimerPage />, handle: { component: InvestmentDisclaimerPage } },

centrifuge-app/src/pages/Pool/Overview/HoldingsTable.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import { PoolMetadata } from '@centrifuge/centrifuge-js'
22
import { Stack, Text } from '@centrifuge/fabric'
33
import { formatBalance } from '../../../../src/utils/formatting'
44
import { DataTable, SortableTableHeader } from '../../../components/DataTable'
5-
import { formatDate } from '../../../utils/date'
5+
import { formatDate, isValidDate } from '../../../utils/date'
66

77
export const HoldingsTable = ({ metadata }: { metadata: PoolMetadata | undefined }) => {
88
const assetsData = metadata?.holdings
99

1010
const format = (value: any, header: string) => {
1111
if (header.includes('date') && !header.includes('quantity')) {
12-
return formatDate(value)
12+
return isValidDate(value) ? formatDate(value) : '-'
1313
}
1414
if (header.includes('%')) {
1515
return `${value}%`
@@ -20,7 +20,8 @@ export const HoldingsTable = ({ metadata }: { metadata: PoolMetadata | undefined
2020
if (header.includes('quantity')) {
2121
return formatBalance(value, '', 2)
2222
}
23-
return value
23+
24+
return !value ? '-' : value
2425
}
2526

2627
const columns = assetsData?.headers.map((header: string, index: number) => {

0 commit comments

Comments
 (0)