⬆️ PAY_DIAMOND Upgrade Tool — REAL PRODUCTION UPGRADE ⚠️ MAINNET
Tool v1.5.2 · Facet bundle v8.14.0
⚠️ REAL UPGRADE — targets the ALREADY-LIVE PAY_DIAMOND, real member data, real gas, real consequence.
This is NOT the fresh-deploy tool (pay-diamond-deploy.html) — that tool only ever
ADDS facets to a brand-new Diamond. This tool REPLACES facets on a Diamond that
is already serving real traffic. Go through the steps below IN ORDER, at your own
pace — every step is independent and resumable (progress auto-saves to this
browser). Step 10 (the actual diamondCut) is the one irreversible on-chain wiring
change — review the Replace/Add/Remove counts on that step carefully before
confirming in your wallet.
Progress backup Every resolved address auto-saves to this browser (localStorage key 'payDiamondUpgradeV1'). Export/Import move progress across devices/browsers; Reset clears everything (asks to confirm).
Step 1 — Connect wallet, verify OWNER + network
Strict OWNER gate, same as every other tool in this project — if the
connected wallet isn't exactly OWNER, every deploy/write button stays disabled.
Step 2 — Set the ALREADY-LIVE PAY_DIAMOND address
Pre-filled with the real T119 mainnet address from
2026-07-19_Diamond_Contract_Reference_MAINNET_v1.md. Edit only if
PAY_DIAMOND is ever redeployed and this address changes.
PAY_DIAMOND:
Steps 3-9 — Deploy the 7 NEW v8.12.0 Payment facets
Each is a fresh, standalone deploy of the updated facet source
(T181 PlanTierHierarchy batch — tierRank, linkedAnnualPlanId, on-chain
descriptionPoints — redeployed on top of the currently-live v8.10.0 Diamond) — no constructor args.
Same manual-override/resumable pattern as pay-diamond-deploy.html: paste a
known address to skip redeploying.
Step 6 — CampaignFacet (version-tag-only for v8.12.0 too — confirmed by real compile: bytecode identical to the live v8.11.0 CampaignFacet except the trailing solc metadata hash; no ABI/selector change)
CampaignFacet:
Step 7 — PlanFacet (⚠️ createPlan/updatePlan signatures CHANGED AGAIN — new trailing tierRank/linkedAnnualPlanId params (T181) mean NEW selectors vs the currently-live v8.10.0 PlanFacet, old ones removed; also gains the brand-new setPlanDescription(uint8,string[]) function — see Step 10)
Step 9 — PaymentCoreFacet (proration engine, partial-payment rate-capping, price-lock snapshot integration, now also carries the new first-vs-repeat-purchase renewalDurationSeconds branch via inlined PaymentStorage.updateMemberOnPayment — no ABI change, largest facet, 15,597/24,576 bytes)
New at T189d, fixed at T190 (tool v1.4.1): categorization no longer trusts a hand-typed
snapshot for the one question that matters most — "does this selector already
exist on the live Diamond right now?" Click "REFRESH LIVE SELECTORS FROM CHAIN"
first — a free, read-only facets() call straight to the real
PAY_DIAMOND — to pull the actual current selector set directly from chain state.
COMPUTE CUT now builds Replace/Add AND Remove against THAT live
data, not the static OLD_SELECTOR_SET array (which is used only to label
selectors with their function name/facet for display, and for the T188b
same-name drift check — never to decide existence or removal). This is the direct fix
for the failure class that caused both T188's revert ("Add" for a selector the chain
already had) and T190's revert ("Remove" for a selector the chain no longer had,
because the Remove list was still built from the stale static snapshot until this fix).
Step 11 — Verify
Calls facets() through the live Diamond and shows every
registered facet address + selector count, so the upgrade can be visually confirmed.