diff --git a/src/app/create/page.tsx b/src/app/create/page.tsx
index db06e049..eb9608ab 100644
--- a/src/app/create/page.tsx
+++ b/src/app/create/page.tsx
@@ -21,6 +21,8 @@ import {
type CommitmentType,
} from '@/lib/commitments';
import { useWallet } from '@/components/WalletProvider';
+import { useProtocolStatus } from '@/components/ProtocolStatusProvider';
+import { getActionPauseReason } from '@/lib/soroban/protocol-status';
import { ESCROW_CONTRACT_ID, explorerContractUrl, config } from '@/lib/config';
import { useProtocolParams } from '@/lib/protocol';
import {
@@ -49,6 +51,9 @@ function daysMessage(reason: DaysError, minDays: number): string {
export default function CreatePage() {
const { address } = useWallet();
+ const protocolStatus = useProtocolStatus();
+ const isPaused = protocolStatus.status === 'ok' && protocolStatus.paused;
+ const pauseReason = getActionPauseReason('create_commitment', isPaused);
const { params, loading: paramsLoading, isFallback } = useProtocolParams();
const [step, setStep] = useState(0);
const [type, setType] = useState('balanced');
@@ -354,13 +359,25 @@ export default function CreatePage() {
{config.networkDetails.label.toLowerCase()} escrow contract is enabled once a contract ID is configured
{ESCROW_CONTRACT_ID ? '.' : ' (none set in this deployment).'}
-
+
-
+
+ {isPaused && (
+
+ {pauseReason}
+
+ )}
+
+
)}
diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx
index f8a06b3e..a3253215 100644
--- a/src/app/dashboard/page.tsx
+++ b/src/app/dashboard/page.tsx
@@ -21,6 +21,9 @@ import {
import { ConfirmDialog } from '@/components/ConfirmDialog';
import { DisputeDialog } from '@/components/DisputeDialog';
import { useWallet } from '@/components/WalletProvider';
+import { useProtocolStatus } from '@/components/ProtocolStatusProvider';
+import { getActionPauseReason } from '@/lib/soroban/protocol-status';
+import { YieldCoverageChip } from '@/components/YieldCoverageChip';
import { fetchXlmBalance, shortAddress } from '@/lib/wallet';
import type { DecodedEscrowEvent } from '@/lib/soroban/events';
import { DISPUTE_CATEGORY_LABELS, type DisputeRecord } from '@/lib/soroban/dispute';
@@ -51,6 +54,9 @@ type BalanceState =
export default function DashboardPage() {
const { status, address } = useWallet();
+ const protocolStatus = useProtocolStatus();
+ const isPaused = protocolStatus.status === 'ok' && protocolStatus.paused;
+ const exitPauseReason = getActionPauseReason('early_exit', isPaused);
const [list, setList] = useState(null);
const [pending, setPending] = useState<{ kind: 'exit' | 'remove'; id: string } | null>(null);
const [announcement, setAnnouncement] = useState('');
@@ -350,9 +356,22 @@ export default function DashboardPage() {
const record = disputeRecords[c.id];
const pct = Math.round(progressOf(c) * 100);
const shown = st === 'settled' || st === 'exited' ? 100 : pct;
- const left =Math.max(0, Math.ceil((maturityOf(c) - Date.now()) / 86_400_000));
+ const left = Math.max(0, Math.ceil((maturityOf(c) - Date.now()) / 86_400_000));
const frozen = st === 'disputed' || st === 'violated';
const ownerIsConnected = !!address && c.owner === address;
+ const isNearOrMatured =
+ st === 'matured' ||
+ (st === 'active' && maturityOf(c) - Date.now() <= 7 * 86_400_000);
+ const isOnChain = !c.demo;
+ const accruedYield = BigInt(
+ (c as any).accrued_yield ?? (c as any).accruedYield ?? projectedYield(c),
+ );
+ const showCoverageWarning =
+ isOnChain &&
+ isNearOrMatured &&
+ protocolStatus.status === 'ok' &&
+ protocolStatus.yieldPool < accruedYield;
+
return (
@@ -389,8 +408,14 @@ export default function DashboardPage() {
Funds are frozen. Loading the dispute record...
)}
+ {showCoverageWarning && (
+
+ )}
-
+
{!frozen && st === 'matured' && (