Skip to content

feat(deepbook-v3): support the margin surface against Pyth's upgraded Core - #1194

Merged
tonylee08 merged 13 commits into
mainfrom
tlee/deepbook-v3-margin-upgraded-pyth
Aug 17, 2026
Merged

feat(deepbook-v3): support the margin surface against Pyth's upgraded Core#1194
tonylee08 merged 13 commits into
mainfrom
tlee/deepbook-v3-margin-upgraded-pyth

Conversation

@tonylee08

@tonylee08 tonylee08 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Description

Pyth is replacing Core with a separately published Sui package rather than upgrading it in place, so pyth::price_info::PriceInfoObject under the upgraded deployment is a distinct Move type. A compatible upgrade cannot change a public function's parameter types, so the existing margin entrypoints can never accept it. deepbook_margin exposes the upgraded surface as parallel modules — margin_manager_upgraded (12 entrypoints), pool_proxy_upgraded (8) — and margin_liquidation as parallel entrypoints in the same module (liquidate_base_upgraded, liquidate_quote_upgraded), all under the same function names. Contract side: MystenLabs/deepbookv3#1170 and MystenLabs/deepbookv3#1211 (DBU-668).

This SDK now targets the upgraded deployment exclusively. Legacy Core is being retired, so carrying both was short-lived complexity for a surface that is about to stop existing. There is no marginPyth switch, no pythUpgraded config and no priceInfoObjectIdUpgraded field: pyth is the upgraded deployment's state objects, priceInfoObjectId is its price object. Every margin method keeps its name and signature — what changed is the module each targets and the price object it passes.

The split is not uniform, and that is the thing to review: margin_manager_upgraded and pool_proxy_upgraded carry only the entrypoints that take a price object. Creation, repayment, referrals, cancels, modifies, settlement withdrawals, staking, governance and every getter exist solely on the base modules and still resolve there. Routing one the wrong way targets a function that does not exist on chain, which is what margin-upgraded-pyth.test.ts pins.

getPriceInfoObjectId(coinKey) and getFeedId(coinKey) replace scattered ! assertions and throw naming the coin. Without them a misconfiguration surfaces as an on-chain EPriceFeedIdMismatch deep inside the oracle read, which does not say which coin was at fault.

Generated bindings were regenerated from the margin package sources; that also picks up managerStates, setReferral and unsetReferral, which had landed on the contract side since the last codegen run. No generated function was removed.

⚠️ Breaking: requires the upgraded margin package on the target network

The upgraded modules do not exist in earlier deepbook_margin publications, so this release must not be used against a network whose margin package predates them. Marked major.

Mainnet margin is now v7 (0x55ee8099…, published 2026-08-17), and MARGIN_PACKAGE_ID points at it — verified on chain as the lineage head, carrying margin_manager_upgraded and pool_proxy_upgraded. Two release gates remain, neither a code change:

  1. enable_version(7) has not run on the mainnet MarginRegistry. v7's gate constant is MARGIN_VERSION = 7 and the live registry does not yet allow it, so every v7 flow aborts EPackageVersionDisabled until that call lands. Do not release before it does.
  2. Mainnet margin_liquidation has no upgraded publication. Its liquidation_vault exposes only liquidate_base/liquidate_quote, not the _upgraded pair the liquidation builders target, so those two builders have no mainnet target until it is upgraded. The rest of the vault surface takes no oracle and is unaffected.

Hermes: v2, and authentication

  • v2 instead of v1. getLatestVaas calls /v2/updates/price/latest and reads binary.data, replacing the deprecated /api/latest_vaas. Both return the same accumulator payload — verified byte-identical for a 2-feed request — but v1 is being retired. Worth knowing: Hermes returns one message covering every requested feed, not one per feed.
  • pythAccessToken, a client-level option sent as Authorization: Bearer <token> on every request. The endpoint serving the upgraded Core answers 401 without it, so before this the update path could not work at all — PriceServiceConnectionConfig had no way to set a header. The name matches the in-flight @mysten/suins migration (feat(suins): migrate to Pyth Pro [SUIP-1111] #1158) so both SDKs take the credential under one name.

No credential ships with the SDK. Consumers supply a token at runtime and talk to Pyth directly. Those who do not are intended to fall back to a DeepBook-operated proxy that supplies credentials server-side — that proxy is not deployed yet, so DEEPBOOK_HERMES_PROXY is undefined and that path throws a ConfigurationError naming the field to set. Wiring its hostname is the one thing outstanding before merge.

Package ids and feeds

Testnet margin was pinned to v14 — two upgrades behind. Both move to the packages carrying the upgraded surface, published from deepbookv3 main and recorded in MystenLabs/deepbookv3#1232:

was now
MARGIN_PACKAGE_ID (testnet) v14 0xe52c1dec… v16 0xce6ab629…
LIQUIDATION_PACKAGE_ID (testnet) v3 0x8d69c3ef… v4 0x29bccec5…

Testnet's MarginRegistry was migrated onto the feed ids upgraded Core carries (SUI→Crypto.SUI/USD, DBUSDC→Crypto.USDC/USD, DEEP→Crypto.DEEP/USD, DBTC→Crypto.BTC/USD; per-coin bounds and max_age_secs unchanged), so the testnet coin map follows. DBTC prices off BTC/USD because the upgraded deployment carries no distinct DBTC feed.

Mainnet XBTC now has an upgraded price object0x4f7ff451…, created 2026-08-17. XBTC is absent from Pyth's Sui push-feed list, so Pyth never maintained one for it on the upgraded deployment; creating it is permissionless, and as on legacy Core it is kept fresh by our own pusher rather than Pyth's. The feed itself was never the problem — Crypto.XBTC/USD carries the same id as legacy and serves live signed data.

Test plan

  • tsc --noEmit, prettier --check, oxlint, and vitest run305 passed. Examples are outside tsconfig (include: ['src']) so they were typechecked separately, also clean.
  • Every shipped (feed, priceInfoObjectId) pair verified on chain to belong to the upgraded Pyth package on its network — 4 testnet, 7 mainnet. This caught mainnet XBTC still holding its legacy object behind a comment claiming it had none.
  • Mainnet re-verified 2026-08-17 against the on-chain price table: resolving each shipped feed id through the upgraded Pyth state returns exactly the priceInfoObjectId this SDK ships, for all 7 — so no shipped pair can send an update to the wrong object.
  • Live on mainnet, through this SDK's own code path: refreshed all 7 configured price objects in one transaction — 3xBRg6c5…. XBTC went from ~32 minutes stale to fresh, which is the one that proves the path end to end: it is the only configured feed Pyth's own pusher does not maintain.
  • margin-upgraded-pyth.test.ts pins the module split: oracle-taking builders target the upgraded modules, oracle-free builders stay on the base modules, liquidations pick the parallel entrypoint, and a coin with no price object throws naming the coin.
  • priceServiceConnection.test.ts pins the wire contract: v2 path and params, auth headers reaching the client, no headers key when unconfigured, the single-combined-message shape, a diagnosable error on a v1-shaped response, and that every shipped endpoint constant is a parseable URL or absent.
  • Live on testnet, through this SDK's own code path:
    • Pushed a signed update to the upgraded Core's BTC/USD object, 33 days stale → fresh — Bpkvp8NN….
    • Refreshed all four configured feeds in one transaction — 5cUt69BH….
    • Landed pool_proxy_upgraded::update_current_price on SUI_DBUSDC using shipped defaults — C2osLSS7…. This runs read_price_upgraded on both legs, so staleness, feed id, EWMA and confidence all passed against the live registry.
  • All four testnet feed ids verified against Pyth's own catalogue by symbol.

Note for callers: the price refresh must ride in the same PTB as the margin call. max_age_secs is 60 on chain, so refreshing in a prior transaction is a race you lose — the first attempt at the above aborted check_price_is_fresh for exactly this reason.

Review

Two independent review passes. The first found three real defects, all fixed and covered by tests:

  1. DEEPBOOK_HERMES_PROXY shipped as a literal placeholder host and became the default endpoint, failing as an opaque TypeError: Invalid URL from inside axios.
  2. Testnet coins paired an upgraded feed with a legacy priceInfoObjectId — two deployments in one pair. Resolved by dropping the legacy identity entirely.
  3. getPriceInfoObjects silently dropped a coin when two coins shared a feed id (reachable: DBTC prices off the generic BTC/USD feed), returning undefined into a move call. Feeds are now deduplicated and the index maps a feed to every coin using it.

The second pass found no behaviour defects; its findings were accuracy fixes (an undercount of mainnet price objects, examples that would throw, a doc block promising a fallback that throws).

Follow-ups, deliberately not here

  • The proxy hostname, and the proxy itself.
  • Mainnet package id bump, once margin is upgraded there.
  • Creating the mainnet XBTC PriceInfoObject.

Related: MystenLabs/sui-operations#8693 (testnet price-pusher stack, blocked on this releasing) and MystenLabs/deepbook-services#147 (mainnet migration script, ordered before this).

State object ids, package versions, feed ids and per-feed price objects were resolved on chain (2026-08-11) rather than transcribed.


AI Assistance Notice

Please disclose the usage of AI. This is primarily to help inform reviewers of how careful they need to review PRs, and to keep track of AI usage across our team. Please fill this out accurately, and do not modify the content or heading for this section!

  • This PR was primarily written by AI.
  • I used AI for docs / tests, but manually wrote the source code.
  • I used AI to understand the problem space / repository.
  • I did not use AI for this PR.

… Core

Pyth is replacing Core with a separately published Sui package rather than upgrading
it in place, so its `PriceInfoObject` is a distinct Move type that the existing margin
entrypoints can never accept — their signatures are frozen by the `compatible` upgrade
policy. `deepbook_margin` therefore exposes the upgraded surface as parallel modules
(`margin_manager_upgraded`, `pool_proxy_upgraded`) and `margin_liquidation` as parallel
entrypoints (`liquidate_base_upgraded`, `liquidate_quote_upgraded`), under the same
function names: callers switch module, not function name.

The SDK follows without changing its own surface. A `marginPyth` setting
(`'legacy' | 'upgraded'`) decides which module each builder targets and whether it
passes `priceInfoObjectId` or the new `priceInfoObjectIdUpgraded`; price feed pushes
follow the same setting via a new `pythUpgraded` state config. Entrypoints that take no
oracle stay on the base modules in both modes, because the upgraded modules do not
carry them.

Both networks ship as `'legacy'`, which is byte-identical to today's behaviour — the
existing PTB snapshots pass unchanged. Neither network can serve the upgraded surface
yet: the margin packages carrying it are not deployed, and neither upgraded Pyth
deployment has an object for every feed its `MarginRegistry` is configured with.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@tonylee08
tonylee08 deployed to sui-typescript-aws-kms-test-env August 11, 2026 18:18 — with GitHub Actions Active
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
sui-typescript-docs Ready Ready Preview Aug 17, 2026 6:27pm

Request Review

…rmes v2

Testnet margin was pinned to v14, two upgrades behind; margin_liquidation to v3.
Move both to the packages that carry the upgraded-Pyth surface — deepbook_margin
v16 (0xce6ab629) and margin_liquidation v4 (0x29bccec5).

Switch price update fetches from the deprecated Hermes v1 /api/latest_vaas to v2
/v2/updates/price/latest. Both return the same accumulator payload — one message
covering all requested feeds, not one per feed — so this is not a behaviour
change today, but v1 is being retired.

Add PythConfig.hermesHeaders, forwarded to every Hermes request. The endpoint
serving Pyth's upgraded Core requires an Authorization header and answers 401
without one, so the update path was unusable in 'upgraded' mode. No credential
ships with the SDK; consumers supply it at runtime.

Verified end to end on testnet: fetched signed update data through this path and
pushed it to the upgraded Core BTC/USD PriceInfoObject
(0x0fcd3e0c…), which went from 33 days stale to fresh
(tx Bpkvp8NNH36KjJ8rZjEj1N5ZJaxLsbSwc5sTUmGWvBa).

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…nt fallback

Follow-up to the review of the previous commit, which shipped three defects.

The proxy fallback constant was a literal placeholder host. Because testnet now
defaults to 'upgraded' and supplies no hermesHeaders, that placeholder became
the default endpoint for every testnet price update, failing as an opaque
`TypeError: Invalid URL` from inside axios. It is now `undefined` until the
proxy exists, and the upgraded path throws a ConfigurationError naming the
field to set. Added a test that every shipped endpoint constant is a parseable
URL or absent.

Testnet coins carried an upgraded `feed` next to a legacy `priceInfoObjectId` —
two different deployments in one pair, so a forced legacy call would fetch one
deployment's update data for the other's object. Testnet now carries the
upgraded identity only; the beta feed ids and legacy price objects are removed,
so legacy mode fails immediately naming the coin. Feed lookup moved behind
config.getFeedId(), replacing the `coin.feed!` assertions.

getPriceInfoObjects dropped a coin whenever two coins shared a feed id — the
reverse index kept only the last key, and the caller got undefined for the
other. Testnet DBTC prices off the generic BTC/USD feed, so this is reachable.
Feeds are now deduplicated before the update is built (a repeated feed would
also emit two update_single_price_feed calls against one object and pay two
fees), and the index maps a feed to every coin using it.

Also: export the Hermes constants, drop an orphaned doc comment, and correct
the changeset, which still claimed both networks ship 'legacy'.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…rror

Second review pass. No behaviour defects this time; the fixes are accuracy and
diagnosability.

Verified all six mainnet priceInfoObjectIdUpgraded values against the upgraded
price table on chain — every one matches, including USDSUI, which had no
corroborating record anywhere. The changeset said "five"; it ships six, now
enumerated.

The three Pyth examples built a client with no upgraded config, so against
testnet — which now defaults to 'upgraded' — they threw on the first stale
feed. They now attach credentials from PYTH_TOKEN when present.

newCoinTypeData was the last direct `coin.feed!` read; it threw 'Coin feed not
found' without naming the coin. Routed through config.getFeedId().

Docs: #hermesEndpoint claimed a proxy fallback that currently throws, and noted
that supplying hermesHeaders without an endpoint sends the token to Pyth's own
host; a doubled JSDoc opener; and a block that had drifted onto getFeedId,
leaving getPriceInfoObjectId undocumented. The dedup comment implied an
in-repo feed collision that does not exist.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…e only

Legacy Core is being retired, so carrying both deployments was short-lived
complexity. Removed: the marginPyth switch, the pythUpgraded config, the
priceInfoObjectIdUpgraded field, and every legacy price object id. `pyth` is
now the upgraded deployment's state objects and `priceInfoObjectId` its price
object; the four routing getters return the upgraded modules unconditionally.

Entrypoints that take no oracle argument still resolve to the base modules,
which is the only place they exist. That split is what the rewritten routing
test pins, since it is no longer expressible as a mode.

BREAKING: this requires the upgraded margin package on the target network. The
upgraded modules do not exist in earlier deepbook_margin publications, so the
release must follow the mainnet package upgrade rather than precede it. Marked
major.

Verified on chain that every shipped (feed, priceInfoObjectId) pair belongs to
the upgraded Pyth package on its network — 4 testnet, 6 mainnet. Mainnet XBTC
had kept its legacy object while carrying a comment claiming it had none; it now
correctly has no object, so pricing it throws until one is created.

Examples take the upgraded config and a PYTH_TOKEN when present. They are not
covered by tsconfig (include: src), so they were checked separately.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
… to be created

DBTC is testnet's wrapped BTC, so it should take the same feed mainnet XBTC
does. It was pointed at plain BTC/USD only because no XBTC price object existed
on upgraded Core; one was created on testnet on 2026-08-11, so testnet now
mirrors the correct mainnet configuration rather than the substitution.

The testnet MarginRegistry was migrated to match in the same operation
(5uWP4ewCReip6htjEZCqapNWKPujhngZTZdAt5cNZXU9), bounds and max_age_secs
unchanged, and the path was verified end to end by pool_proxy_upgraded::
update_current_price on DBTC_DBUSDC (FM1CNGwQf8obhU9hdmceZNdatk4npbBoc1ChgvarsyBx),
which runs read_price_upgraded on both legs.

Mainnet XBTC's missing priceInfoObjectId now says what to do about it: the feed
is live, only the object is absent, and creating it takes one ordinary
transaction from any funded address rather than an admin action.

Verified on chain that every shipped price object carries exactly the feed id
its coin config claims — a tighter check than "is it an upgraded object", and
the one that would have caught a mismatched pair.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Both SDKs in this repo consume the same Pyth credential and had converged on
the same design independently, under different names: suins takes
`pythAccessToken` -> `accessToken`, deepbook took a generic `hermesHeaders` map.
These are public API after release, so align now rather than ship two shapes.

`accessToken` is also the narrower, more correct type here. The endpoint choice
keys off whether the caller brought credentials, and with a header map that test
was wrong: any header at all — a trace id, say — routed the caller to Pyth's
authenticated host, where they would 401. A token means what the branch assumes.

Added `pythAccessToken` at the client level too. Supplying `pyth` replaces the
whole config, so setting only a credential silently dropped the built-in state
object ids; the client option composes instead. Verified against the live
endpoint: state ids preserved, 200 OK.

Adopted two details from the suins implementation while aligning: `ids[]` is
serialized explicitly rather than relying on axios's array encoding — which the
mocked test could not have caught changing — and `parsed: false` drops the
response half we never read.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…echeck the tests

Independent review found the runtime logic sound and the defects concentrated in
prose — including two claims that would have shipped as public release notes.

The `@mysten/suins` attribution was false. suins takes no such credential in any
published version: `accessToken` exists only on the draft migration branch
(ts-sdks#1158). Both the changeset and the JSDoc asserted an existing
cross-SDK convention; they now name it as a convergence target on unpublished
work, which is what it is.

DBTC was documented as pricing off BTC/USD in three places while the code uses
Crypto.XBTC/USD — the constants file contradicted itself six lines apart. The
header, the changeset and the dedup comment were written before 2ac9b54 moved
the feed and never updated. An integrator building a coin map from the release
note would have wired the wrong feed id.

The dedup comment also cited testnet DBTC as an example of two coins sharing a
feed. No shipped map has a collision; the guard is for caller-supplied maps, and
it now says so.

The test file did not typecheck: `Parameters<typeof PriceServiceConnection>`
does not accept a class, which silently degraded the config parameter to
`undefined`, so `connection({ accessToken })` was passing an argument the type
system rejected. Tests are outside tsconfig (include: src) so nothing caught it.
Fixed to ConstructorParameters, plus a narrowing failure.

Added test/unit/queries/priceFeedQueries.test.ts: endpoint selection had zero
coverage, despite being the code that decides where a credential is sent. It
pins the no-credential ConfigurationError, that the failure names the field
rather than surfacing from inside axios, and that an explicit hermesEndpoint
wins with the token following it there — now documented rather than implicit.

Also: export PriceServiceConnectionConfig, document the pyth/pythAccessToken
precedence, and record why an empty token is treated as absent.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
USDSUI's coin data is correct against Pyth — object exists, is an upgraded-Core
object, and its internal feed id matches. But the mainnet MarginRegistry's
PythConfig configures six currencies and USDSUI is not one of them, so an
oracle-taking margin call aborts in the registry's currency lookup before the
feed id is compared. Recorded at the constant so the next reader does not
conclude from valid-looking ids that the path works.

Lending is unaffected (margin_pool supply/withdraw take no oracle) and no USDSUI
DeepBook pool is margin-registered, so nothing is broken today.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@tonylee08
tonylee08 deployed to sui-typescript-aws-kms-test-env August 12, 2026 15:34 — with GitHub Actions Active
@tonylee08
tonylee08 marked this pull request as ready for review August 14, 2026 17:00
@tonylee08
tonylee08 requested a review from a team as a code owner August 14, 2026 17:00
@tonylee08
tonylee08 deployed to sui-typescript-aws-kms-test-env August 14, 2026 17:00 — with GitHub Actions Active
@tonylee08
tonylee08 marked this pull request as draft August 14, 2026 17:00
Created on Pyth's upgraded Core on 2026-08-17 (tx 3SbNisBM…ePnSx), so the last
mainnet feed gap is closed — all six mainnet-configured coins now have an
upgraded price object.

Worth recording why this was ours to create: XBTC is absent from Pyth's Sui
push-feed list entirely, so Pyth never maintained an object for it on this
chain. The legacy one exists because our own price pusher pushes it, and the
upgraded one will be kept fresh the same way. Creation is permissionless, so no
admin action or multisig was involved.

Verified on chain: the object is of the upgraded Core type, carries exactly the
feed id the SDK claims for XBTC, is registered in the upgraded price table
(98 -> 99 feeds), and accepts updates (tx 2HEUjwau…Ra5Kf).

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@tonylee08
tonylee08 deployed to sui-typescript-aws-kms-test-env August 17, 2026 16:31 — with GitHub Actions Active
@tonylee08
tonylee08 marked this pull request as ready for review August 17, 2026 16:31
@tonylee08
tonylee08 deployed to sui-typescript-aws-kms-test-env August 17, 2026 16:31 — with GitHub Actions Active
…lication

Mainnet `deepbook_margin` was upgraded to v7 on 2026-08-17, so
`MARGIN_PACKAGE_ID` moves to `0x55ee8099…`. It is the same lineage as the
v6 id it replaces (original `0x97d94737…`, matching `MARGIN_V1`) and its
`margin_manager_upgraded` / `pool_proxy_upgraded` function sets are
identical to testnet v16's, so every builder resolves the same way on both
networks.

Two mainnet preconditions this does not satisfy, both recorded in-code and
in the changeset rather than left implicit:

- v7 carries `MARGIN_VERSION = 7` and the live `MarginRegistry` allows
  `{5, 6}`, so its flows abort `EPackageVersionDisabled` until
  `enable_version(7)` runs. Do not release before that call lands.
- Mainnet `margin_liquidation` has no upgraded publication — its
  `liquidation_vault` exposes only `liquidate_base`/`liquidate_quote`, not
  the `_upgraded` pair `MarginLiquidationsContract` targets. Those two
  builders have no mainnet target until it is upgraded. The rest of the
  vault surface takes no oracle and is unaffected.

Package version, lineage and module surface read on chain (2026-08-17).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
XBTC is a distinct asset from BTC — its own peg and redemption risk — so
substituting Crypto.BTC/USD misstates collateral in exactly the stress
where the two diverge. That is not a configuration choice, so pin it with
a test instead of a comment: mainnet XBTC and testnet DBTC (same
underlying) must carry the XBTC/USD feed, and the BTC/USD id must appear
for no coin on either network.

Verified the test fails when mainnet XBTC is pointed at BTC/USD.

The wider confidence band on XBTC is a separate question, answered by the
registry's max_conf_bps bound, not by pricing a different asset.
…e docs

An axios error carries config.headers, and both JSON.stringify(err) and
err.toJSON() serialize it — so a caller logging a failed Hermes request
would print the bearer token. getLatestVaas now catches and re-throws a
plain error carrying status and response body only. Verified the new test
fails when the raw error is allowed to escape.

Also: dropped an orphaned JSDoc block above #oracleCalls in three files
(only the second attached, and the first still described the legacy/
upgraded 'both modes' toggle this PR removed); corrected an example
comment claiming 4 mainnet assets carry feeds when 7 do; and softened a
test comment that claimed to check a URL is resolvable when it checks
parseability.
@tonylee08
tonylee08 merged commit 504644c into main Aug 17, 2026
9 checks passed
@tonylee08
tonylee08 deleted the tlee/deepbook-v3-margin-upgraded-pyth branch August 17, 2026 18:56
tonylee08 added a commit that referenced this pull request Aug 18, 2026
…ded-Pyth publication (#1214)

* chore(deepbook-v3): point mainnet LIQUIDATION_PACKAGE_ID at the upgraded-Pyth publication

Mainnet `margin_liquidation` v4 (`0xf17bff1b…`) predates the upgraded-Pyth
entrypoints: its `liquidation_vault` exposes `liquidate_base`/`liquidate_quote`
only, while `MarginLiquidationsContract` targets the `_upgraded` pair. That left
`liquidateBase` and `liquidateQuote` with no mainnet target in 2.0.0 — the
second of the two release gates recorded in #1194.

`LIQUIDATION_PACKAGE_ID` now points at the publication that closes it,
`0xba2b39c0…`.

The id is not on chain yet — `object(address:)` against mainnet GraphQL returns
null — so nothing here is verified against a live package: not the version, not
the lineage, not the module surface. Draft until the upgrade lands and those
three are read on chain. The rest of the vault surface (deposit, withdraw,
balance, swaps, trader authorization) takes no oracle and works against either
id.

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

* chore(deepbook-v3): record the mainnet liquidation upgrade as live

The id is now published as margin_liquidation v5. Its liquidation_vault exposes
liquidate_base_upgraded and liquidate_quote_upgraded, and its LIQUIDATION_VAULT
type is still defined by the lineage's original 0x73c59388…, so the deployed
vault stays valid across the upgrade.

* chore(deepbook-v3): drop the liquidation package id comment

The id change speaks for itself; the reasoning lives in the changeset and the
PR.

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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