Skip to content

feat(ops): re-term and restart the demo in the order that works - #32

Merged
edycutjong merged 2 commits into
mainfrom
feat/reterm-script
Sep 9, 2026
Merged

edycutjong merged 2 commits into
mainfrom
feat/reterm-script

Conversation

@edycutjong

Copy link
Copy Markdown
Owner

The demo subscription cannot survive a judging window at the shipped terms.

A renewal that re-arms costs ~1.55 ℏ of gas to collect 1 ℏ, so at a 90-second period the reserve drains in minutes. Measured live just now:

now:  1 HBAR per 90s · 5 calls · reserve arms 3
      = 4.5 minutes of life

Covering 72 hours at 90 s would need ~4,464 ℏ. A longer period is the only affordable fix — 72 renewals an hour apart instead of 2,880.

Order is load-bearing, and the script enforces it

setTerms snapshots into each Subscription at subscribe() time (RetainerAccess.sol:178), so a subscription opened before the re-term keeps the old period for its whole life. Restart first and you have re-armed the same trap.

The non-obvious half

Raising the price does not fix the drain. The three pots are separate: a subscription payment lands in refundable/revenue, while scheduled calls are paid out of gasReserve, which only fundGasReserve() and syncReserve() feed. Topping up the reserve is the actual fix; the longer period is what makes it last.

Guards

  • refuses to run if SELLER_PRIVATE_KEY is not the immutable beneficiary (setTerms is onlyBeneficiary)
  • refuses a period under MIN_PERIOD_SECONDS (61)
  • DRY_RUN=1 prints the plan and the arithmetic, sends nothing
  • warns when the funded reserve does not reach the judging window
DRY_RUN=1 yarn hardhat run scripts/retermAndRestart.ts --network hederaTestnet

next: 1 HBAR per 3600s · 5 calls
      +120 HBAR reserve ≈ 75 re-arming renewals at ~1.6 HBAR each
      ≈ 75.0 hours of unattended life

Keys are read from ~/.config/retainer/hedera.env like the other ops scripts; nothing is committed or printed. Lint and check-types clean.

The demo subscription cannot survive a judging window at the shipped terms. A
renewal that re-arms costs ~1.55 HBAR of gas to collect 1 HBAR, so at a 90-second
period the reserve drains in minutes -- measured at 3 renewals remaining, which
is 4.5 minutes of life. Covering 72 hours at 90s would need ~4,464 HBAR.

A longer period is the only affordable fix: 72 renewals an hour apart instead of
2,880 at ninety seconds. This script does the three calls that get there.

Order is load-bearing and the script enforces it. setTerms snapshots into each
Subscription at subscribe() time, so a subscription opened before the re-term
keeps the old period for its whole life -- restart first and you have re-armed
the same trap.

The non-obvious half: raising the price does not fix the drain. The three pots
are separate. A subscription payment lands in refundable/revenue, while
scheduled calls are paid out of gasReserve, which only fundGasReserve() and
syncReserve() feed. Topping up the reserve is the actual fix; the longer period
is what makes the top-up last.

Refuses to run if SELLER_PRIVATE_KEY is not the immutable beneficiary, or if the
requested period is under MIN_PERIOD_SECONDS, and DRY_RUN=1 prints the
arithmetic without sending. It warns when the funded reserve does not reach the
judging window.

Dry-run against the live contract reads: 1 HBAR per 90s, reserve arms 3 = 4.5
minutes; 3600s with +120 HBAR = ~75 hours.
@vercel

vercel Bot commented Sep 9, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
build Ready Ready Preview Sep 9, 2026 4:00pm UTC

The first version took RESERVE_HBAR as a number with a default of 120. At a
one-hour period that is 75 renewals -- 75 hours -- which lapses 2026-09-12,
two days BEFORE judging starts on 09-14. A plausible-looking default that
quietly misses the only date that matters is worse than no default.

Funding is now derived from UNTIL (default 2026-09-16T23:59Z, the end of
judging): renewals = hours / period, reserve = renewals x re-arm cost, and the
subscription is funded for the same horizon. Both can still be overridden.

It also now prints the SUBSCRIPTION cost, which the first version omitted
entirely. The two pots are funded separately and either can run out first, so
the warnings name which one is short rather than saying "short".

Measured through the end of judging, from the live contract:
  3600s  282 gas + 177 subs = 459 HBAR
  7200s  141 gas +  89 subs = 230 HBAR
 14400s   71 gas +  45 subs = 116 HBAR
@edycutjong
edycutjong merged commit f389f25 into main Sep 9, 2026
9 checks passed
@edycutjong
edycutjong deleted the feat/reterm-script branch September 9, 2026 16:08
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