feat(staking): warn on empty reward-pool contracts [OPE-1846]#2080
Merged
Conversation
Surface a non-blocking warning when a staking contract's reward pool is empty (availableRewards === 0). Previously the app computed isRewardsAvailable but never used it: users could select/keep a rewards-exhausted contract with no signal, and the middleware would silently deploy the service unstaked (stake omitted, deploy proceeds). - New shared NoStakingRewardsAlert (type="warning"), optional "Switch Staking Contract" action. - Migration/onboarding: per-card warning in SelectActivityRewardsConfiguration when the contract has no rewards; card stays selectable (useCanMigrate unchanged — non-blocking). - Main page: warning added to AgentDisabledAlert, rendered alongside the self-hiding low-balance alerts so neither is masked. Gating reads loaded contract details (availableRewards === 0), not raw isRewardsAvailable, to avoid flashing during load / firing on no_staking. Tests: NoStakingRewardsAlert render + switch button; StakingRewardsWarning load/available/empty gating. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… audit gate) Five HIGH advisories were failing the "yarn audit (both trees)" CI gate. They are newly-published advisories in existing transitive deps (not introduced by this branch) — pre-existing on staging too: - immutable >=5.0.0-beta.1 <5.1.8 (GHSA-v56q-mh7h-f735 List trie DoS, GHSA-xvcm-6775-5m9r Map/Set hash-collision DoS) via sass>immutable. The resolution already pinned immutable to 5.1.5 (still vulnerable) in both trees; bumped to 5.1.9. - fast-uri >=3.0.0 <=3.1.3 (GHSA-v2hh-gcrm-f6hx, GHSA-4c8g-83qw-93j6 host-confusion) via electron-store>conf>ajv>fast-uri. Root resolution bumped 3.1.2 -> 3.1.4. - sharp <0.35.0 (GHSA-f88m-g3jw-g9cj, libvips CVE-2026-33327/33328/ 35590/35591) via next>sharp. Added a sharp 0.35.3 resolution in both trees. New transitive @img/colour is MIT and new @img/sharp-* wasm variants are Apache-2.0 (both allowlisted); @img/sharp-libvips-* covered by the existing prefix exemption. audit:prod now green on both trees. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sharp 0.35 removed its install/check.js postinstall script (now prebuilt-only via @img/sharp-* binary packages), so `sharp` no longer appears in the install-hook surface. The install-hooks gate fails on the now-stale allowlist entry in both trees. Removed it from root and frontend allowlists. The new @img/* prebuilt packages declare no install scripts, so nothing new needs allowlisting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ROMAN-VALORY
approved these changes
Jul 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Ticket #1175 / OPE-1846: an Omenstrat agent (service 3768) was deployed and actively trading but showed no staking status/history. Root cause: the target contract
pearl_beta_mech_marketplace_1had an empty reward pool (availableRewards == 0), so the middleware silently omitted the stake from the deploy mega-batch (WARNING only, deploy proceeds) — the service runs and trades but is unstaked, and the app rendered a blank staking panel with no explanation.The frontend already computed
isRewardsAvailable/hasEnoughRewardsAndSlotsbut never used them: users could select or stay on a rewards-exhausted contract with zero signal. Slots were gated everywhere; rewards were not.Changes (non-blocking warnings — no gating behavior changed)
NoStakingRewardsAlert(type="warning"): "No staking rewards available — reward pool is currently empty; the agent can still run but won't earn until it's refilled." Optional Switch Staking Contract action.SelectActivityRewardsConfiguration): per-card warning when a contract's reward pool is empty. Card stays selectable —useCanMigrateis untouched.AgentDisabledAlert): warning shown when the selected contract hasavailableRewards === 0, rendered alongside the self-hiding low-balance alerts so neither is masked.Gating reads loaded contract details (
availableRewards === 0/stakingContractInfo && !isRewardsAvailable), not rawisRewardsAvailable, to avoid flashing during load or firing onno_staking(query disabled → undefined).Tests
NoStakingRewardsAlert— message render + optional switch button.StakingRewardsWarning— load / rewards-available / empty-pool gating.SelectStakingPage+AgentInfosuites pass (72).lint:frontend0 errors,typecheckclean.Out of scope / notes
AgentDisabledAlert/index.tsxhas no unit-test harness (only its sub-alerts are tested in isolation); the equivalent gating pattern is covered by theStakingRewardsWarningtest.Screenshots
🤖 Generated with Claude Code