Skip to content

Commit c761403

Browse files
committed
fix display actual vault balance in emergency mode
1 parent 55f51bc commit c761403

File tree

7 files changed

+107
-42
lines changed

7 files changed

+107
-42
lines changed

apps/hub/src/app/_components/emergency-bar.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { AlertIcon, ExternalIcon } from '@status-im/icons/20'
1+
import { AlertIcon } from '@status-im/icons/20'
22
import { ButtonLink } from '@status-im/status-network/components'
33

44
const EmergencyBar = () => {
@@ -16,14 +16,14 @@ const EmergencyBar = () => {
1616
>
1717
Withdraw funds
1818
</ButtonLink>
19-
<ButtonLink
19+
{/* <ButtonLink
2020
variant="secondary"
2121
size="24"
2222
icon={<ExternalIcon />}
2323
href="https://status.im/blog/contracts-compromised"
2424
>
2525
Learn More
26-
</ButtonLink>
26+
</ButtonLink> */}
2727
</div>
2828
</div>
2929
)

apps/hub/src/app/_components/hub-layout.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
import { useState } from 'react'
33

44
import { Divider, Footer } from '@status-im/status-network/components'
5+
import { useReadContract } from 'wagmi'
56

7+
import { STAKING_MANAGER } from '../_constants/address'
68
import { EmergencyBar } from './emergency-bar'
79
import { Sidebar } from './sidebar'
810
import { TopBar } from './top-bar'
@@ -13,6 +15,14 @@ interface HubLayoutProps {
1315

1416
export function HubLayout({ children }: HubLayoutProps) {
1517
const [sidebarOpen, setSidebarOpen] = useState(false)
18+
const { data: emergencyModeEnabled } = useReadContract({
19+
address: STAKING_MANAGER.address,
20+
abi: STAKING_MANAGER.abi,
21+
functionName: 'emergencyModeEnabled',
22+
query: {
23+
refetchInterval: 30000,
24+
},
25+
})
1626

1727
return (
1828
<div className="relative isolate z-10 min-h-screen w-full bg-neutral-100 px-1 pb-1">
@@ -21,7 +31,7 @@ export function HubLayout({ children }: HubLayoutProps) {
2131

2232
{/* Main Content Area */}
2333
<div className="relative w-full overflow-hidden rounded-20 bg-white-100">
24-
<EmergencyBar />
34+
{Boolean(emergencyModeEnabled) && <EmergencyBar />}
2535
<div className="flex h-[calc(100vh-64px-123px)] w-full flex-row overflow-hidden lg:h-[calc(100vh-64px-50px)]">
2636
{/* Sidebar */}
2737
<Sidebar isOpen={sidebarOpen} onClose={() => setSidebarOpen(false)} />

apps/hub/src/app/_components/vaults/table-columns.tsx

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,16 @@ interface TableColumnsProps {
2222
}
2323

2424
// Calculate total staked across all vaults
25-
const calculateTotalStaked = (vaults: StakingVault[]): bigint => {
25+
const calculateTotalStaked = (
26+
vaults: StakingVault[],
27+
emergencyMode: boolean
28+
): bigint => {
2629
return vaults.reduce(
27-
(acc, vault) => acc + (vault.data?.stakedBalance || 0n),
30+
(acc, vault) =>
31+
acc +
32+
(emergencyMode
33+
? vault.data?.depositedBalance || 0n
34+
: vault.data?.stakedBalance || 0n),
2835
BigInt(0)
2936
)
3037
}
@@ -71,7 +78,10 @@ export const createVaultTableColumns = ({
7178
// isConnected,
7279
}: TableColumnsProps) => {
7380
// Calculate totals and current time once per column creation
74-
const totalStaked = calculateTotalStaked(vaults)
81+
const totalStaked = calculateTotalStaked(
82+
vaults,
83+
Boolean(emergencyModeEnabled)
84+
)
7585
const totalKarma = calculateTotalKarma(vaults)
7686
const currentTimestamp = getCurrentTimestamp()
7787
const columnHelper = createColumnHelper<StakingVault>()
@@ -112,12 +122,15 @@ export const createVaultTableColumns = ({
112122
},
113123
}),
114124
columnHelper.accessor('data.stakedBalance', {
115-
header: 'Staked',
125+
header: emergencyModeEnabled ? 'Vault balance' : 'Staked',
116126
cell: ({ row }) => {
127+
const balance = emergencyModeEnabled
128+
? row.original.data?.depositedBalance
129+
: row.original.data?.stakedBalance
117130
return (
118131
<div className="flex items-center gap-1">
119132
<span className="text-[13px] font-medium text-neutral-100">
120-
{formatSNT(row.original.data?.stakedBalance || 0n)}
133+
{formatSNT(balance || 0n)}
121134
<span className="ml-0.5 text-neutral-50">SNT</span>
122135
</span>
123136
</div>
@@ -276,9 +289,17 @@ export const createVaultTableColumns = ({
276289
}
277290
onClose={() => setOpenModalVaultId(null)}
278291
vaultAddress={row.original.address}
279-
amountWei={row.original.data?.stakedBalance || 0n}
292+
amountWei={row.original.data?.depositedBalance || 0n}
280293
>
281-
<Button variant="danger" size="24" iconBefore={<AlertIcon />}>
294+
<Button
295+
variant="danger"
296+
size="24"
297+
iconBefore={<AlertIcon />}
298+
disabled={
299+
!row.original.data?.depositedBalance ||
300+
row.original.data.depositedBalance === 0n
301+
}
302+
>
282303
Withdraw funds
283304
</Button>
284305
</WithdrawVaultModal>

apps/hub/src/app/_constants/address.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import {
88
import type { Abi, Address } from 'viem'
99

1010
export const STAKING_MANAGER = {
11-
address: '0x5cDf1646E4c1D21eE94DED1DA8da3Ca450dc96D1' as Address,
11+
address: '0x1Fb4Cf49a23F1dA6ac74fCc5c1caF028Fc07a296' as Address,
1212
abi: stakingManagerAbi as Abi,
1313
} as const
1414

1515
export const VAULT_FACTORY = {
16-
address: '0xddDcd43a0B0dA865decf3e4Ae71FbBE3e2DfFF14' as Address,
16+
address: '0xe07399ca807D981a4e28029307a8A985a5fA2cd1' as Address,
1717
abi: vaultFactoryAbi as Abi,
1818
} as const
1919

apps/hub/src/app/_hooks/useStakingVaults.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useAccount, useChainId, useConfig } from 'wagmi'
44
import { readContract, readContracts } from 'wagmi/actions'
55

66
import { vaultAbi } from '~constants/contracts'
7-
import { STAKING_MANAGER } from '~constants/index'
7+
import { SNT_TOKEN, STAKING_MANAGER } from '~constants/index'
88

99
// ============================================================================
1010
// Types
@@ -29,6 +29,8 @@ export interface StakingVaultData {
2929
lockUntil: bigint
3030
/** Total rewards accrued and available for claiming */
3131
rewardsAccrued: bigint
32+
/** Actual token balance in the vault (from availableWithdraw) - reliable in emergency mode */
33+
depositedBalance: bigint
3234
}
3335

3436
/**
@@ -116,32 +118,47 @@ async function fetchVaultData(
116118
functionName: 'lockUntil',
117119
args: [],
118120
},
121+
{
122+
chainId,
123+
address: SNT_TOKEN.address,
124+
abi: SNT_TOKEN.abi,
125+
functionName: 'balanceOf',
126+
args: [vaultAddress],
127+
},
119128
],
120129
})
121130

122-
// Check if both contract calls succeeded
123-
const [vaultResult, lockUntilResult] = results
131+
// Check if all contract calls succeeded
132+
const [vaultResult, lockUntilResult, depositedBalanceResult] = results
124133

125134
if (
126135
vaultResult.status !== 'success' ||
127-
lockUntilResult.status !== 'success'
136+
lockUntilResult.status !== 'success' ||
137+
depositedBalanceResult.status !== 'success'
128138
) {
129139
console.error(
130140
`Failed to fetch vault data for ${vaultAddress}:`,
131141
vaultResult.status !== 'success'
132142
? vaultResult.error
133-
: lockUntilResult.error
143+
: lockUntilResult.status !== 'success'
144+
? lockUntilResult.error
145+
: depositedBalanceResult.error
134146
)
135147
return null
136148
}
137149

138150
// Extract the actual data from successful results
139-
const vaultData = vaultResult.result as Omit<StakingVaultData, 'lockUntil'>
151+
const vaultData = vaultResult.result as Omit<
152+
StakingVaultData,
153+
'lockUntil' | 'depositedBalance'
154+
>
140155
const lockUntil = lockUntilResult.result as bigint
156+
const depositedBalance = depositedBalanceResult.result as bigint
141157

142158
return {
143159
...vaultData,
144160
lockUntil,
161+
depositedBalance,
145162
}
146163
} catch (error) {
147164
// Log error for debugging but don't throw - allows partial results

apps/hub/src/app/_hooks/useVaultEmergencyExit.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
import { useMutation, type UseMutationResult } from '@tanstack/react-query'
1+
import {
2+
useMutation,
3+
type UseMutationResult,
4+
useQueryClient,
5+
} from '@tanstack/react-query'
26
import { type Address, formatUnits } from 'viem'
37
import { useAccount, useConfig, useWriteContract } from 'wagmi'
48
import { waitForTransactionReceipt } from 'wagmi/actions'
59

610
import { vaultAbi } from '~constants/contracts'
711
import { SNT_TOKEN, statusNetworkTestnet } from '~constants/index'
8-
import { useMultiplierPointsBalance } from '~hooks/useMultiplierPoints'
9-
import { useStakingVaults } from '~hooks/useStakingVaults'
1012
import { useVaultStateContext } from '~hooks/useVaultStateContext'
1113

1214
// ============================================================================
@@ -95,9 +97,8 @@ export function useVaultEmergencyExit(): UseVaultEmergencyExitReturn {
9597
const { address } = useAccount()
9698
const { writeContractAsync } = useWriteContract()
9799
const config = useConfig()
100+
const queryClient = useQueryClient()
98101
const { send: sendVaultEvent, reset: resetVault } = useVaultStateContext()
99-
const { refetch: refetchStakingVaults } = useStakingVaults()
100-
const { refetch: refetchMultiplierPoints } = useMultiplierPointsBalance()
101102

102103
return useMutation({
103104
mutationKey: [MUTATION_KEY_PREFIX, address],
@@ -146,8 +147,13 @@ export function useVaultEmergencyExit(): UseVaultEmergencyExitReturn {
146147
throw new Error('Transaction was reverted')
147148
}
148149

149-
// Transaction successful, refetch data and close dialog
150-
await Promise.all([refetchStakingVaults(), refetchMultiplierPoints()])
150+
// Transaction successful, invalidate cache to force fresh data from blockchain
151+
await queryClient.invalidateQueries({
152+
queryKey: ['staking-vaults'],
153+
})
154+
await queryClient.invalidateQueries({
155+
queryKey: ['multiplier-points-balance'],
156+
})
151157
resetVault()
152158
} catch (error) {
153159
// Transaction failed or user rejected

apps/hub/src/app/stake/page.tsx

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ export default function StakePage() {
7171
const weightedBoost = useWeightedBoost(vaults)
7272
const { data: exchangeRate } = useExchangeRate()
7373

74+
const { data: emergencyModeEnabled } = useReadContract({
75+
address: STAKING_MANAGER.address,
76+
abi: STAKING_MANAGER.abi,
77+
functionName: 'emergencyModeEnabled',
78+
query: {
79+
refetchInterval: 30000,
80+
},
81+
})
82+
7483
const form = useForm<FormValues>({
7584
resolver: zodResolver(createStakeFormSchema()),
7685
mode: 'onChange',
@@ -422,24 +431,26 @@ export default function StakePage() {
422431
</form>
423432

424433
<div className="flex flex-col gap-[18px]">
425-
<div className="rounded-32 border border-neutral-10 bg-white-100 p-8 shadow-2">
426-
<div className="mb-2 flex items-start justify-between">
427-
<p className="text-13 font-500 text-neutral-60">
428-
Total staked
434+
{!emergencyModeEnabled && (
435+
<div className="rounded-32 border border-neutral-10 bg-white-100 p-8 shadow-2">
436+
<div className="mb-2 flex items-start justify-between">
437+
<p className="text-13 font-500 text-neutral-60">
438+
Total staked
439+
</p>
440+
</div>
441+
<div className="mb-4 flex items-end gap-2">
442+
<SNTIcon />
443+
<span className="text-27 font-600">
444+
{formatSNT(totalStaked ?? 0, {
445+
includeSymbol: true,
446+
})}
447+
</span>
448+
</div>
449+
<p className="text-13 font-500 text-neutral-40">
450+
Next unlock in 356 days
429451
</p>
430452
</div>
431-
<div className="mb-4 flex items-end gap-2">
432-
<SNTIcon />
433-
<span className="text-27 font-600">
434-
{formatSNT(totalStaked ?? 0, {
435-
includeSymbol: true,
436-
})}
437-
</span>
438-
</div>
439-
<p className="text-13 font-500 text-neutral-40">
440-
Next unlock in 356 days
441-
</p>
442-
</div>
453+
)}
443454

444455
<div className="rounded-32 border border-neutral-10 bg-white-100 p-8 shadow-2">
445456
<div className="mb-2 flex items-start justify-between">

0 commit comments

Comments
 (0)