Repository navigation
feat(staking): persistent 'OIS rewards paused' banner - #3980
Conversation
Replace the auto-opening Changelog modal with a persistent, non-dismissible banner announcing that Oracle Integrity Staking rewards are paused. The modal popped on every page load, was dismissed with no persistence, and left no in-app signal that OIS is paused once closed. Its copy was also imprecise: only the reward rate is 0 (OP-PIP-103, 22 April 2026) — staking and slashing remain live, so stake assigned to a publisher is still subject to slashing. The banner says so explicitly and links to the April 2026 governance update. The banner is suppressed on the geo-blocked and governance-only segments, where the legal notice already renders and OIS is unavailable, and is gated behind the OIS_PAUSED env var (enabled by default) so it can be removed with a single config change when rewards resume. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Addresses PR review feedback: the banner rendered above the VPN-blocked screen, advertising unstake/withdraw on a route that exposes no staking functionality. Adds VPN_BLOCKED_SEGMENT to the restricted-mode check and a component test covering the enabled, disabled, and restricted-segment states.
`asBoolean` treated any value other than "true" as false, so `OIS_PAUSED=1` or a typo like `=ture` silently removed a notice about ongoing slashing risk. Match "true"/"false" explicitly and throw otherwise, which fails the build rather than shipping a page missing the notice. Swap the file's dead eslint-disable comments for the biome equivalents; the repo has no eslint config, and biome lints changed files in full, so editing this file surfaced its pre-existing process.env usages.
|
Greenlight — 🚫 Blocked — see reasons below ( Blocking reasons:
|
1 similar comment
|
Greenlight — 🚫 Blocked — see reasons below ( Blocking reasons:
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
6 Skipped Deployments
|
There was a problem hiding this comment.
🔍 OIS_PAUSED is a build-time constant on a statically prerendered route
OIS_PAUSED is read at module evaluation in apps/staking/src/config/server.ts:67-71 and consumed by the root layout, which is statically prerendered for /. Changing the env var in Vercel will not remove the banner without a redeploy. The author flags this and asks for sign-off — worth an explicit confirmation from an owner, since the intended off-switch ("when rewards resume") is slower than an env-var flip suggests.
(Refers to lines 67-71)
Was this helpful? React with 👍 or 👎 to provide feedback.
| const isRestrictedMode = | ||
| segment === GEO_BLOCKED_SEGMENT || | ||
| segment === GOVERNANCE_ONLY_SEGMENT || | ||
| segment === VPN_BLOCKED_SEGMENT; | ||
|
|
||
| // These segments render the restricted / blocked screens, where OIS is | ||
| // unavailable and the legal notice may already be showing, so the banner | ||
| // would either stack with it or advertise actions the user can't take. | ||
| // Render an empty node when hidden to keep the `<body>` grid row count | ||
| // stable. | ||
| return isEnabled && !isRestrictedMode ? ( |
There was a problem hiding this comment.
🔍 Banner hidden on governance-only/vpn-blocked where unstake/withdraw is still possible
Users rewritten to governance-only and vpn-blocked can still reach unstake/withdraw flows (see the restricted-region copy at apps/staking/src/components/Root/restricted-region-banner.tsx:28-30), yet the slashing/zero-rewards notice is suppressed for them. RestrictedRegionBanner only covers geo-blocked and governance-only, so on vpn-blocked no notice at all is shown. Intentional per the PR description (avoid stacking with the legal notice), but the vpn-blocked case leaves the user with neither banner.
Was this helpful? React with 👍 or 👎 to provide feedback.
Replaces the auto-opening
Changelogmodal on the staking app with a persistent, non-dismissible banner announcing that Oracle Integrity Staking rewards are paused.The modal was dismissible and only appeared once per page load, so a user could miss it entirely and not realise that stake assigned to a publisher is still subject to slashing while earning nothing. The banner states that plainly and stays on the page.
Changes
ois-paused-banner.tsx(new) — the banner. Rendered under the header, above the page content. Hidden on thegeo-blocked,governance-only, andvpn-blockedsegments, which render blocked/restricted screens where OIS is unavailable and the legal notice may already be showing. Renders an empty node when hidden so the<body>grid row count stays stable.Root/index.tsx— swaps<Changelog />for<OisPausedBanner />and adds the matchinggrid-rowstrack (5→6 at mobile, 4→5 atlg).Changelog/index.tsx— deleted; the banner supersedes it and nothing else referenced it.config/server.ts— adds theOIS_PAUSEDflag, defaulting to on.OIS_PAUSED=falseremoves the banner when rewards resume.turbo.json— declaresOIS_PAUSEDfor thebuild:verceltask so turbo caching keys on it.Copy and the link target match the OIS docs banner and callout that landed in #3968, so the two surfaces stay consistent.
OIS_PAUSEDis a build-time flag/is statically prerendered, so the flag is baked in at build time — flipping it in the Vercel dashboard does nothing until a redeploy. This is noted in the doc comment on the export. Please confirm that redeploy-to-toggle is acceptable before merging.Unrecognised values throw rather than defaulting. Parsing anything-but-
"true"asfalsewould meanOIS_PAUSED=1or a typo like=turesilently removing a notice about ongoing slashing risk; throwing fails the build instead, which is the safer failure for permanent copy making an explicit risk claim.Notes
/region-blockedis a legacy route that nothing links or rewrites to (the middleware only rewrites togeo-blocked,governance-only, andvpn-blocked). It renders a blocked screen and does show the banner. The gating matches the three segments actually in the blocking flow; left alone rather than adding a fourth magic string for an unreachable page.config/server.tscarriedeslint-disablecomments for a linter this repo no longer has a config for. Biome lints changed files in full, so editing the file surfaced its pre-existingprocess.envusages; the comments are swapped for the biome equivalents, matchingapps/mcp/src/config.ts.Verification
CI=1 pnpm exec turbo build test --filter @pythnetwork/staking— 16/16 tasks, 53 tests.Behaviour exercised against a running dev server, driving
x-vercel-ip-countrywithBLOCKED_REGIONS=fr GOVERNANCE_ONLY_REGIONS=us:DE(unrestricted)US(governance-only)FR(geo-blocked)Flag matrix, same server:
OIS_PAUSEDtrue/TRUEfalse/False1/tureInvalidEnvironmentErrorA production
next buildconfirms/is○ (Static), that the prerenderedindex.htmlcontains the banner whilegeo-blocked/governance-only/vpn-blockeddo not, and that an invalidOIS_PAUSEDfails the build rather than shipping a page missing the notice.