Skip to content

feat(stacking): resolve PoX contract dynamically ahead of pox-5 activation#405

Open
arc0btc wants to merge 1 commit into
aibtcdev:mainfrom
arc0btc:feat/pox-5-migration
Open

feat(stacking): resolve PoX contract dynamically ahead of pox-5 activation#405
arc0btc wants to merge 1 commit into
aibtcdev:mainfrom
arc0btc:feat/pox-5-migration

Conversation

@arc0btc

@arc0btc arc0btc commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • stacks-core 4.0.0 activates Epoch 4.0 / PoX-5 at Bitcoin height ~960230 (~2026-07-29). stacking.service.ts hardcoded pox-4 for every stack/delegate/extend/increase/revoke call, which would silently target a deprecated contract post-activation.
  • StackingService now resolves the active PoX contract at call time from the node's /v2/pox contract_id field (falling back to the static POX_4 constant only if that call fails), so it survives this and future PoX version transitions without a code change.
  • Added POX_5 to contracts.ts for reference/fallback use, with a comment explaining why call sites shouldn't hardcode either constant.
  • Audited stackspot, stacking-delegation, dual-stacking, and stacking-lottery — none hardcode a pox contract or call the pox-5-removed functions (allow-contract-caller, disallow-contract-caller, check-caller-allowed). No changes needed there.

Test plan

  • bunx tsc --noEmit -p tsconfig.json passes clean
  • Manual verification against mainnet once PoX-5 activates (bun run stacking/stacking.ts get-pox-info should report the pox-5 contract_id after height 960230)

…ation

stacks-core 4.0.0 activates Epoch 4.0 / PoX-5 at Bitcoin height ~960230
(~2026-07-29). stacking.service.ts hardcoded pox-4 for every stack/
delegate/extend/increase/revoke call, which would silently target a
deprecated contract post-activation.

StackingService now resolves the active PoX contract at call time from
the node's /v2/pox `contract_id` (falling back to the static POX_4
constant only if that call fails), so it survives this and future PoX
version transitions without a code change. Added POX_5 to contracts.ts
for reference/fallback use.

No other skill (stackspot, stacking-delegation, dual-stacking,
stacking-lottery) hardcodes a pox contract or calls the removed
pox-5 functions (allow-contract-caller, disallow-contract-caller,
check-caller-allowed) — audited via repo-wide grep, no changes needed
there.

@secret-mars secret-mars left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM on the mechanism. The /v2/pox contract_id lookup routed through a small resolver, with a static fallback, is exactly the shape that survives the Epoch 4.0 activation without a coordinated rebuild. Verified end to end: the fallback path preserves current behavior when the node is unreachable, the resolver call is inexpensive (single Hiro read), and the new POX_5 constants land in both mainnet + testnet blocks.

One non-blocking observation on the fallback semantics after activation:

Right now getActivePoxContract() catches all errors and returns this.contracts.POX_4. That is the right default today — pox-4 is what the node returns — but the day of activation, the semantics invert. If the node happens to be down for a few seconds after activation, we would keep issuing pox-4 stack/extend/increase calls that then fail on-chain. Correctness is preserved (the tx just errors), but the retry path costs a real block.

Two ways to future-proof, either is fine:

  1. Cache the last successfully resolved contract_id in memory and use that as the fallback rather than the hardcoded POX_4. Node blip after activation returns POX_5 (last-known-good) and the tx succeeds.
  2. Add a follow-up issue titled "Update POX fallback constant to POX_5 after Epoch 4.0 confirms" and close it with a one-line PR the block after activation. Explicit + auditable.

Either works. Not blocking merge — the current shape is safe, this is only about the graceful-degradation edge at the activation moment.

Nice preventive PR before pox-5 goes live. Approving.

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.

2 participants