Conversation
|
● Reviewed · against Note Approved. Removes the chain-agnostic raw-block sentinel from AssessmentThis collapses a two-branch predicate into one canonical definition of permanence, deleting Iteration history · 2 reviews2026-08-21 23:07 UTC · ✅ approved · 0 findings ·
|
There was a problem hiding this comment.
Note
✅ Approved — see full review in the sticky comment ↑
Graphite Automations"Request reviewers once CI passes on sdks monorepo" took an action on this PR • (08/21/26)1 assignee was added and 3 reviewers were added to this PR based on Siyu Jiang (See-You John)'s automation. |
…n only (LP-1362) BREAKING CHANGE: removes PERMANENT_UNLOCK_BLOCK_THRESHOLD and the raw-block form of isPermanentTimelock. The block form now requires chainId + endBlock. The chain-agnostic threshold could not express "1000 years" on every chain (~76,000 years at 12 s/block, ~634 at 0.1 s), so which locks it caught depended on the chain it was applied to, and it could not see a permanent lock on a slow chain at all (~2.6e9 blocks at 12 s, three orders under the 2e11 bound). It had no remaining caller: the only production call site already passed chainId and endBlock, and the serving path the raw form was added for has both in scope. One row changes in the field. 4663_0xC5EdF1… (2026-07-08) carries a horizon of PERMANENT_TIMELOCK_REQUEST_SECONDS / 12 = 262,800,000,000 blocks — the 100k-year Permanent preset converted at 12 s/block, a day before 4663's 0.1 s cadence was registered. At the real cadence that is 833 years, so it is now finite. That agrees with the classifier, which already stored is_quick_launch = false for it; the raw-block form was what made serving disagree. Checked against all 2,642 prod auction_liquidity_locks rows — it is the only row the two rules differ on. 230 SDK tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9e91f6f to
fbd2a87
Compare
What
isPermanentTimelocknow always judges permanence from the real time horizon past the auction end. The chain-agnostic raw-block form is gone.Breaking:
PERMANENT_UNLOCK_BLOCK_THRESHOLDdeleted.PermanentTimelockParamsno longer accepts{unlockBlock}alone; the block form requireschainId+endBlock.'burn'/'creatorFees') short-circuit unchanged.Why the raw-block form had to go
It was a single block count standing in for a duration, so its meaning changed per chain — 2e11 blocks is ~76,000 years at 12 s/block and ~634 years at 0.1 s. Two consequences:
isPermanentTimelockwithchainId/endBlock; only the serving path used the raw form. Same lock, two answers.And it had no caller left to protect. Across
sdks,backendanduniversethere is exactly one production call site —data-api/src/bl/workers/auction/quickLaunch.ts:135— and it already passeschainId,endBlock,unlockBlock. The serving path the raw form was introduced for hasauction.end_blockandauction.chain_idin scope at the call site.The one row that changes
A stored unlock block encodes the block time believed when the lock was created. Chain 4663 has one row converted at the wrong cadence:
The conversion predates 4663's
0.1entry inBLOCK_TIME_SECONDS_BY_CHAINby one day. Every 4663 permanent lock from 2026-07-13 on is31,536,000,000,000— exactly 1.0000× the 0.1 s conversion. This is the only row from the gap.Critically, this is not a regression: the classifier already stored
is_quick_launch = falsefor that auction, because it already used the chain-aware form. The raw-block threshold was what made serving claimlocked_forever: truefor a lock the classifier had already judged finite. Removing it makes the two agree.Verified against all 2,642 production
auction_liquidity_locksrows joined to their auctions: this is the only row where the raw-block and horizon rules differ.Tests
The sentinel describe block is replaced by three cases on the real data: the mis-converted 4663 horizon reading finite at the chain it actually runs at, the same request converted at the correct cadence reading permanent, and a permanent mainnet lock whose raw block number (~2.6e9) is far too small for any raw-block bound to have seen.
Two pre-existing tests used the removed
{lockMode, unlockBlock}shape and now passchainId/endBlock— the block-form equivalents were already asserted alongside them, so no coverage is lost.bun test→ 230 pass / 0 fail (15 files)tsc --noEmit -p tsconfig.types.json→ cleanFollow-up (not in this PR)
On the version bump, Uniswap/backend#12485's serving call site moves from
{lockMode, unlockBlock}to{lockMode, chainId, endBlock, unlockBlock}, and its boundary test is rewritten against the horizon. Part of LP-1362.🤖 Generated with Claude Code