Skip to content

fix(tests): correct stale stake-pool fixtures and program-id mocks - #2452

Closed
dcccrypto wants to merge 3 commits into
playgroundfrom
fix/stake-pool-test-owner-mismatch
Closed

fix(tests): correct stale stake-pool fixtures and program-id mocks#2452
dcccrypto wants to merge 3 commits into
playgroundfrom
fix/stake-pool-test-owner-mismatch

Conversation

@dcccrypto

Copy link
Copy Markdown
Owner

Second slice of the 65 failures #2450 exposed (first was #2451). Fixes 8, adds 2. Test files only — no product change.

Two stale mocks, one cluster

1. The fixtures used an account layout no decoder reads. They packed lpMint@65 / vault@97 / cooldownSlots@162. decodeStakePoolV1 reads 104 / 136 / 184 — corroborated independently by parseStakePool in app/app/api/stake/pools/route.ts, the route that reads live pools. So the hook was right and the fixture was wrong.

Worth noting why only the cooldown tests failed: the mint/vault reads still produced a valid PublicKey (any 32 bytes are), and unpackMint/unpackAccount are mocked to fixed balances regardless of which account was fetched. The balance and user-share tests were passing vacuously. Only cooldownSlots/depositCap, actually read as numbers, surfaced the mismatch.

2. The pool was owned by the wrong program. The by-pool hooks resolve the stake program from getConfig().vaultProgramId, not the SDK's getStakeProgramId(). The tests still owned the pool account with the SDK's old devnet id, so every run tripped this guard:

if (!poolInfo.owner.equals(stakeProgramId)) {
  throw new Error('Stake pool account owner mismatch — possible network misconfiguration.');
}

That also explains the odd TypeError: resolveFirst is not a function in the double-submit tests — the first deposit() threw before reaching sendTx, so mockImplementationOnce never ran and the resolver was never assigned. One root cause, two symptoms.

What changed

  • Fixtures rebuilt at the real v1 offsets, with the offset table named and commented
  • @/lib/config mocked so vaultProgramId and the pool account's owner are pinned to the same key
  • Dropped the now-dead SDK mocks (STAKE_PROGRAM_ID, getStakeProgramId, STAKE_POOL_SIZE, decodeStakePool) and let the real decodeStakePoolV1 run — the fixture is now validated by a real decoder instead of a stub
  • Added a deliberate test for the owner-mismatch guard on both by-pool hooks. It's a defense-in-depth check that every test was tripping accidentally and none asserted. Verified non-vacuous: disabling the guard fails it, restoring it passes.

Evidence

  • 95 → 87 failures on this branch, 3 stake files → 0
  • npx tsc --noEmit clean
  • 28/28 passing across the three files
cd app && npx vitest run __tests__/hooks/useStakePool.test.ts \
  __tests__/hooks/useStakeDepositByPool.test.ts \
  __tests__/hooks/useStakeWithdrawByPool.test.ts

Stacks cleanly with #2451 — different files, both based on playground.

🤖 Generated with Claude Code

Second slice of the 65 CI failures #2450 exposed. Fixes 8, adds 2.

All three files mocked a contract the hooks stopped using:

1. Wrong account layout. The fixtures packed lpMint@65 / vault@97 /
   cooldownSlots@162, which matches no decoder. `decodeStakePoolV1` reads
   104 / 136 / 184 — independently corroborated by `parseStakePool` in
   app/app/api/stake/pools/route.ts, the route that reads live pools. The
   mint/vault reads still yielded *a* PublicKey (any 32 bytes are valid) and
   unpackMint/unpackAccount are mocked to fixed balances regardless of which
   account was fetched, so the balance and share tests were passing
   vacuously — only the cooldown fields, actually read as numbers, showed it.

2. Wrong stake program. The by-pool hooks resolve it from
   getConfig().vaultProgramId, not the SDK's getStakeProgramId(). The tests
   still owned the pool account with the SDK's old devnet id, so every run
   tripped the owner-mismatch guard. That also explains the "resolveFirst is
   not a function" double-submit failures: the first deposit threw before
   reaching sendTx, so mockImplementationOnce never ran.

Dropped the now-dead SDK mocks (STAKE_PROGRAM_ID, getStakeProgramId,
STAKE_POOL_SIZE, decodeStakePool) and let the real decodeStakePoolV1 run
against a correctly-built buffer, so the fixtures are checked by a real decoder
rather than a stub.

Adds a deliberate test for the owner-mismatch guard on both by-pool hooks — it
was being tripped accidentally by every test but asserted by none. Verified
non-vacuous: disabling the guard fails it, restoring it passes.

Test files only, no product change. 95 -> 87 failures on this branch,
tsc --noEmit clean, no stake test still failing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 21, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
percolator-launch Ready Ready Preview, Comment Jul 23, 2026 6:47am
percolator-mainnet Ready Ready Preview, Comment Jul 23, 2026 6:47am
percolator-playground Ready Ready Preview, Comment Jul 23, 2026 6:47am

Request Review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 64afe969-faf6-420a-b089-6e040bd48dea

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/stake-pool-test-owner-mismatch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@dcccrypto

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

The 2026-07 fee-split merge made lib/v17-engine-config.ts import
V17_MARKET_GROUP_OFF from @percolatorct/sdk. The stake hooks pull that in
transitively, so the two by-pool stake test files' SDK mock must now define it
or the module fails to load ("No V17_MARKET_GROUP_OFF export ... Did you forget
to return it from vi.mock"). Adds the export; all 3 stake suites green (28).
@dcccrypto

Copy link
Copy Markdown
Owner Author

Closing as superseded — this landed upstream independently.

The test-maintenance batch merged into playground (now 8bab3ced) fixed the stale stake-pool fixtures and program-id drift in 03d3f79 (test: migrate stuck-slab and stake-pool fixtures to their current contracts).

Verified on the current base rather than assumed:

  • I ran the full suite on 8bab3ced alone. It is down to 14 failures / 4 files, and none of them are in this PR's target files — they pass on the base as-is.
  • Re-checked specifically for this PR's scope: nothing left for it to fix.
  • This branch now conflicts with playground for the same reason: upstream edited the very files it touches.

Rebasing it would produce a no-op at best, so closing rather than leaving a stale PR in the queue.

For what it's worth the remaining 14 failures are covered by the three PRs I'm keeping open: #2451 (useWallet + ConnectButton, 7), #2459 (Header nav, 4), #2458 (Portfolio PORT-007, 1). With those three stacked the suite is 2823 passed, 0 failed.

@dcccrypto dcccrypto closed this Jul 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant