From eabd95cb83dad87b23cb4b31e1b3345f04fe524f Mon Sep 17 00:00:00 2001 From: Foulk plb | Morpho <71005796+Foulks-Plb@users.noreply.github.com> Date: Thu, 23 Jul 2026 13:13:39 +0200 Subject: [PATCH 1/3] feat: default shared-liquidity target utilization to 90% (no major bump) Reworks the "hardcode 90%" change to be non-breaking. Instead of removing the tuning surface, keep it and mark it @deprecated, and change only the default constant values. No public symbol is removed, renamed, or retyped, so morpho-sdk and liquidity-sdk-viem stay on a minor bump. morpho-sdk (minor): - DEFAULT_SUPPLY_TARGET_UTILIZATION and DEFAULT_WITHDRAWAL_TARGET_UTILIZATION are now both 90% (were 90.5% and 92%). - PublicAllocatorOptions.maxWithdrawalUtilization / defaultMaxWithdrawalUtilization and ReallocationComputeOptions.supplyTargetUtilization / defaultSupplyTargetUtilization are @deprecated but still honored. liquidity-sdk-viem (minor): - LiquidityParameters and the LiquidityLoader parameters argument are @deprecated. The source-market withdrawal ceiling defaults to 90% and the API targetWithdrawUtilization field is no longer consulted; explicit parameters overrides are still honored. wdk-protocol-lending-morpho-evm cascades a patch. Tests, JSDoc, and the changeset are updated; the parity suite pins the legacy 92% default so it stays algorithm-only. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../shared-liquidity-target-utilization-90.md | 29 +++++++++++++++ .../liquidity-sdk-viem/src/loader.test.ts | 12 +++++-- packages/liquidity-sdk-viem/src/loader.ts | 35 +++++++++++-------- .../entities/reallocationData.metrics.test.ts | 12 ++++--- .../src/entities/reallocationData.test.ts | 14 ++++++++ packages/morpho-sdk/src/helpers/constant.ts | 14 +++++--- .../morpho-sdk/src/types/sharedLiquidity.ts | 20 +++++++++-- 7 files changed, 108 insertions(+), 28 deletions(-) create mode 100644 .changeset/shared-liquidity-target-utilization-90.md diff --git a/.changeset/shared-liquidity-target-utilization-90.md b/.changeset/shared-liquidity-target-utilization-90.md new file mode 100644 index 000000000..b5f288f3d --- /dev/null +++ b/.changeset/shared-liquidity-target-utilization-90.md @@ -0,0 +1,29 @@ +--- +"@morpho-org/morpho-sdk": minor +"@morpho-org/liquidity-sdk-viem": minor +"@morpho-org/wdk-protocol-lending-morpho-evm": patch +--- + +Default the shared-liquidity target utilization to 90% and deprecate all +customization of it. This is non-breaking: the tuning surface stays in place and +explicit overrides are still honored until the next major. + +**`@morpho-org/morpho-sdk`**: + +- `DEFAULT_SUPPLY_TARGET_UTILIZATION` and `DEFAULT_WITHDRAWAL_TARGET_UTILIZATION` + are now both 90% (previously 90.5% and 92%). Callers that pass no explicit + override now trigger reallocations at 90% and cap phase-1 source-market + withdrawals at 90%. The aggressive fallback still drains to 100% as a last resort. +- `PublicAllocatorOptions.maxWithdrawalUtilization` / + `defaultMaxWithdrawalUtilization` and + `ReallocationComputeOptions.supplyTargetUtilization` / + `defaultSupplyTargetUtilization` are now `@deprecated`. They remain fully + functional and will be removed in the next major. + +**`@morpho-org/liquidity-sdk-viem`**: + +- `LiquidityParameters` and the `LiquidityLoader` `parameters` constructor + argument are now `@deprecated`. The source-market withdrawal ceiling defaults to + 90% and the Morpho API's `targetWithdrawUtilization` field is no longer + consulted; explicitly passed `parameters` overrides are still honored until the + next major. diff --git a/packages/liquidity-sdk-viem/src/loader.test.ts b/packages/liquidity-sdk-viem/src/loader.test.ts index 2465a119e..32ed1f845 100644 --- a/packages/liquidity-sdk-viem/src/loader.test.ts +++ b/packages/liquidity-sdk-viem/src/loader.test.ts @@ -633,25 +633,31 @@ describe.sequential("LiquidityLoader.fetch", () => { ]); }); - test("uses caller-provided withdrawal utilization options", async () => { + test("caps source withdrawals at the default 90% utilization, ignoring the API value", async () => { + // The API advertises a 100% source ceiling, but it is no longer consulted: + // the source sits at 90% utilization (900 borrow / 1000 supply) and the + // default 90% ceiling lets nothing be pulled. If the API's 100% were still + // read, 100 assets would be withdrawable — so `[]` proves it is ignored. const cappedHandle = setupLoaderMockClient({ blockTimestamp: 100n, targetPendingCapValue: 10_000n, sourceBorrowAssets: 900n, }); - mockApiMarkets(900000000000000000n); + mockApiMarkets(MathLib.WAD); const capped = await new LiquidityLoader(cappedHandle.client).fetch( targetMarketId, ); expect(capped.withdrawals).toStrictEqual([]); + // The deprecated `parameters.maxWithdrawalUtilization` override is still + // honored: forcing 100% drains the source down to that utilization. const overrideHandle = setupLoaderMockClient({ blockTimestamp: 100n, targetPendingCapValue: 10_000n, sourceBorrowAssets: 900n, }); - mockApiMarkets(900000000000000000n); + mockApiMarkets(MathLib.WAD); const override = await new LiquidityLoader(overrideHandle.client, { maxWithdrawalUtilization: { diff --git a/packages/liquidity-sdk-viem/src/loader.ts b/packages/liquidity-sdk-viem/src/loader.ts index 06c866257..b824cafbf 100644 --- a/packages/liquidity-sdk-viem/src/loader.ts +++ b/packages/liquidity-sdk-viem/src/loader.ts @@ -14,15 +14,26 @@ import { getBlock } from "viem/actions"; import { apiSdk } from "./api/index.js"; const REALLOCATION_SIMULATION_DELAY = 3_600n; +/** + * Optional tuning for the shared-liquidity source-market withdrawal ceiling. + * + * @deprecated The source-market withdrawal ceiling is fixed at 90% + * (`DEFAULT_WITHDRAWAL_TARGET_UTILIZATION` in `@morpho-org/morpho-sdk`) and will + * stop being configurable in the next major. Overrides are still honored for now. + */ export interface LiquidityParameters { /** * The default maximum utilization allowed to reach to find shared liquidity (scaled by WAD). + * + * @deprecated Fixed at 90% and will be removed in the next major. */ defaultMaxWithdrawalUtilization?: bigint; /** * If provided, defines the maximum utilization allowed to reach for each market, defaulting to `defaultMaxWithdrawalUtilization`. - * If not, these values are fetched from Morpho API. + * + * @deprecated Fixed at 90% and will be removed in the next major. The Morpho + * API's `targetWithdrawUtilization` is no longer consulted. */ maxWithdrawalUtilization?: Record; } @@ -40,6 +51,10 @@ export class LiquidityLoader { constructor( public client: Client, + /** + * @deprecated The source-market withdrawal ceiling is fixed at 90% and will + * stop being configurable in the next major. Overrides are still honored for now. + */ public readonly parameters: LiquidityParameters = {}, ) { this.dataLoader = new DataLoader( @@ -170,25 +185,17 @@ export class LiquidityLoader { ), }); - const maxWithdrawalUtilization = - parameters.maxWithdrawalUtilization ?? - fromEntries( - // biome-ignore lint/suspicious/noShadow: TODO rename to avoid shadowing - allVaultsMarkets.flatMap(([, markets]) => - markets.map((market) => [ - market.uniqueKey, - market.targetWithdrawUtilization, - ]), - ), - ); - return apiMarkets.map(({ uniqueKey, targetBorrowUtilization }) => { try { + // The source-market withdrawal ceiling defaults to 90% + // (DEFAULT_WITHDRAWAL_TARGET_UTILIZATION) inside + // `getMarketPublicReallocations`; the API's per-market + // `targetWithdrawUtilization` is no longer consulted. Deprecated + // `parameters` overrides are still forwarded for backward compatibility. const { data: endState, withdrawals } = startState.getMarketPublicReallocations(uniqueKey, { ...parameters, timestamp: block.timestamp + REALLOCATION_SIMULATION_DELAY, - maxWithdrawalUtilization, enabled: true, }); diff --git a/packages/morpho-sdk/src/entities/reallocationData.metrics.test.ts b/packages/morpho-sdk/src/entities/reallocationData.metrics.test.ts index 8e09ef0a9..4506378e9 100644 --- a/packages/morpho-sdk/src/entities/reallocationData.metrics.test.ts +++ b/packages/morpho-sdk/src/entities/reallocationData.metrics.test.ts @@ -15,6 +15,7 @@ import { ReallocationData } from "./reallocationData.js"; const VAULT_A: Address = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; const TIMESTAMP = 1_700_000_000n; const NINETY_PERCENT = (9n * MathLib.WAD) / 10n; +const EIGHTY_PERCENT = (8n * MathLib.WAD) / 10n; const targetParams = new MarketParams(WethUsdsBlue); const sourceParamsA = new MarketParams(CbbtcUsdcBlue); @@ -120,19 +121,20 @@ describe("ReallocationData.getAvailableLiquidityToUtilization", () => { ).toBe(580n * MathLib.WAD); }); - test("behavior: returns only own headroom when supplyTargetUtilization > utilization", () => { - // Default supplyTarget (90.5%) > target (90%) → reallocation would not - // trigger, so available liquidity is excluded: ownHeadroom = 400. + test("behavior: returns only own headroom when the supply target exceeds the queried utilization", () => { + // Default supply target (90%) > queried utilization (80%) → reallocation + // would not trigger, so available liquidity is excluded: ownHeadroom to 80% = + // 1000·0.8 − 500 = 300. const data = makeData(); stubReallocations(data, [ { id: sourceParamsA.id, vault: VAULT_A, assets: 200n * MathLib.WAD }, ]); expect( - data.getAvailableLiquidityToUtilization(targetParams.id, NINETY_PERCENT, { + data.getAvailableLiquidityToUtilization(targetParams.id, EIGHTY_PERCENT, { timestamp: TIMESTAMP, }), - ).toBe(400n * MathLib.WAD); + ).toBe(300n * MathLib.WAD); }); test("behavior: returns only scaled available liquidity when utilization equals current utilization", () => { diff --git a/packages/morpho-sdk/src/entities/reallocationData.test.ts b/packages/morpho-sdk/src/entities/reallocationData.test.ts index 88b1af323..67ab93e51 100644 --- a/packages/morpho-sdk/src/entities/reallocationData.test.ts +++ b/packages/morpho-sdk/src/entities/reallocationData.test.ts @@ -36,6 +36,14 @@ const VAULT: Address = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; const OTHER_VAULT: Address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; const LOAN_TOKEN: Address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; +/** + * The withdrawal-utilization default used by the legacy `SimulationState` + * reference (92%). `morpho-sdk` now defaults to 90%, so parity cases that omit an + * explicit ceiling pin the new implementation to this legacy value to keep the + * algorithmic comparison exact. + */ +const LEGACY_DEFAULT_WITHDRAWAL_UTILIZATION = 92_0000000000000000n; + type LegacyPublicAllocatorOptions = { readonly enabled?: boolean; readonly reallocatableVaults?: Address[]; @@ -354,6 +362,12 @@ const toReallocationOptions = ( options: PublicAllocatorOptions = {}, ): PublicAllocatorOptions => ({ ...options, + // The legacy reference defaults its withdrawal ceiling to 92%; morpho-sdk now + // defaults to 90%. Pin the new impl to the legacy default when a case sets none + // explicitly, so the parity comparison stays algorithm-only (not default-driven). + defaultMaxWithdrawalUtilization: + options.defaultMaxWithdrawalUtilization ?? + LEGACY_DEFAULT_WITHDRAWAL_UTILIZATION, timestamp: TIMESTAMP, }); diff --git a/packages/morpho-sdk/src/helpers/constant.ts b/packages/morpho-sdk/src/helpers/constant.ts index 0dbd6eb85..36b41b20d 100644 --- a/packages/morpho-sdk/src/helpers/constant.ts +++ b/packages/morpho-sdk/src/helpers/constant.ts @@ -11,14 +11,20 @@ export const DEFAULT_LLTV_BUFFER = MathLib.WAD / 200n; export const MAX_ABSOLUTE_SHARE_PRICE = 100n * MathLib.RAY; /** - * The default maximum utilization allowed to reach when withdrawing shared liquidity. + * The default maximum utilization a source market may reach when withdrawing + * shared liquidity, scaled by WAD. Still overridable through the deprecated + * `maxWithdrawalUtilization` / `defaultMaxWithdrawalUtilization` options until + * the next major. */ -export const DEFAULT_WITHDRAWAL_TARGET_UTILIZATION = 92_0000000000000000n; +export const DEFAULT_WITHDRAWAL_TARGET_UTILIZATION = 90_0000000000000000n; /** - * The default target utilization above which shared liquidity reallocations are triggered. + * The default target utilization above which shared liquidity reallocations are + * triggered (and the level the target market is brought back to), scaled by WAD. + * Still overridable through the deprecated `supplyTargetUtilization` / + * `defaultSupplyTargetUtilization` options until the next major. */ -export const DEFAULT_SUPPLY_TARGET_UTILIZATION = 90_5000000000000000n; +export const DEFAULT_SUPPLY_TARGET_UTILIZATION = 90_0000000000000000n; /** * Tokens that require setting allowance from zero before changing approval. diff --git a/packages/morpho-sdk/src/types/sharedLiquidity.ts b/packages/morpho-sdk/src/types/sharedLiquidity.ts index 036bb001e..77d6499fe 100644 --- a/packages/morpho-sdk/src/types/sharedLiquidity.ts +++ b/packages/morpho-sdk/src/types/sharedLiquidity.ts @@ -23,6 +23,10 @@ export interface PublicAllocatorOptions { /** * The maximum utilization each source market may reach when withdrawing * shared liquidity, scaled by WAD. + * + * @deprecated The source-market withdrawal ceiling is fixed at 90% + * ({@link DEFAULT_WITHDRAWAL_TARGET_UTILIZATION}) and will stop being + * configurable in the next major. Per-market overrides are still honored for now. */ readonly maxWithdrawalUtilization?: Readonly< Record @@ -31,7 +35,11 @@ export interface PublicAllocatorOptions { /** * The default maximum utilization source markets may reach when withdrawing * shared liquidity, scaled by WAD. - * @default 92% (920000000000000000n) + * + * @default 90% (900000000000000000n) + * @deprecated The source-market withdrawal ceiling is fixed at 90% + * ({@link DEFAULT_WITHDRAWAL_TARGET_UTILIZATION}) and will stop being + * configurable in the next major. Overrides are still honored for now. */ readonly defaultMaxWithdrawalUtilization?: bigint; } @@ -84,6 +92,10 @@ export interface ReallocationComputeOptions extends PublicAllocatorOptions { * Per-market target utilization above which the shared liquidity algorithm * is triggered (scaled by WAD). Overrides `defaultSupplyTargetUtilization` * for the specified market. + * + * @deprecated The supply-target trigger is fixed at 90% + * ({@link DEFAULT_SUPPLY_TARGET_UTILIZATION}) and will stop being configurable + * in the next major. Per-market overrides are still honored for now. */ readonly supplyTargetUtilization?: Readonly< Record @@ -92,7 +104,11 @@ export interface ReallocationComputeOptions extends PublicAllocatorOptions { /** * The default target utilization above which the shared liquidity algorithm * is triggered (scaled by WAD). - * @default 90.5% (905000000000000000n) + * + * @default 90% (900000000000000000n) + * @deprecated The supply-target trigger is fixed at 90% + * ({@link DEFAULT_SUPPLY_TARGET_UTILIZATION}) and will stop being configurable + * in the next major. Overrides are still honored for now. */ readonly defaultSupplyTargetUtilization?: bigint; } From 0124240e9424238ffd47cf425311cccb7bf4948f Mon Sep 17 00:00:00 2001 From: Foulk plb | Morpho <71005796+Foulks-Plb@users.noreply.github.com> Date: Thu, 23 Jul 2026 15:33:27 +0200 Subject: [PATCH 2/3] fix: re-record legacy loader fork plans and require morpho-sdk ^5.4.0 peer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pinned-block fork tests in liquidity-sdk-viem/test/loader.test.ts still asserted withdrawal plans computed with the API-provided per-market ceilings; re-record them against the fixed 90% default. Bump the morpho-sdk peer range to ^5.4.0 since the 90% ceiling ships with that release — an older peer would silently keep the 92% default now that the API value is ignored. Co-Authored-By: Claude Fable 5 --- .../shared-liquidity-target-utilization-90.md | 4 ++ packages/liquidity-sdk-viem/package.json | 2 +- .../liquidity-sdk-viem/test/loader.test.ts | 59 ++++++++----------- 3 files changed, 28 insertions(+), 37 deletions(-) diff --git a/.changeset/shared-liquidity-target-utilization-90.md b/.changeset/shared-liquidity-target-utilization-90.md index b5f288f3d..1e0a0872a 100644 --- a/.changeset/shared-liquidity-target-utilization-90.md +++ b/.changeset/shared-liquidity-target-utilization-90.md @@ -27,3 +27,7 @@ explicit overrides are still honored until the next major. 90% and the Morpho API's `targetWithdrawUtilization` field is no longer consulted; explicitly passed `parameters` overrides are still honored until the next major. +- The `@morpho-org/morpho-sdk` peer range moves to `^5.4.0`: the 90% default + ceiling lives in `morpho-sdk`'s `DEFAULT_WITHDRAWAL_TARGET_UTILIZATION`, so an + older peer would silently fall back to the previous 92% default now that the + API value is no longer consulted. diff --git a/packages/liquidity-sdk-viem/package.json b/packages/liquidity-sdk-viem/package.json index 93409d940..6829f644f 100644 --- a/packages/liquidity-sdk-viem/package.json +++ b/packages/liquidity-sdk-viem/package.json @@ -31,7 +31,7 @@ "peerDependencies": { "@morpho-org/blue-sdk": "^6.0.0", "@morpho-org/blue-sdk-viem": "^5.0.0", - "@morpho-org/morpho-sdk": "^5.0.0", + "@morpho-org/morpho-sdk": "^5.4.0", "@morpho-org/morpho-ts": "^2.7.0", "dataloader": "^2.2.3", "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0", diff --git a/packages/liquidity-sdk-viem/test/loader.test.ts b/packages/liquidity-sdk-viem/test/loader.test.ts index 8acae3b9b..d56bcabea 100644 --- a/packages/liquidity-sdk-viem/test/loader.test.ts +++ b/packages/liquidity-sdk-viem/test/loader.test.ts @@ -20,20 +20,10 @@ describe("dataloader", () => { expect(reallocations).toStrictEqual([ { - assets: 3873700460362n, + assets: 1609457675962n, id: "0x3a85e619751152991742810df6ec69ce473daef99e28a64ab2340d7b7ccfee49", vault: "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", }, - { - assets: 1511034176993n, - id: "0x64d65c9a2d91c36d56fbc42d69e979335320169b3df63bf92789e2c8883fcc64", - vault: "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", - }, - { - assets: 89n, - id: "0x3bb29b62affbedc60b8446b235aaa349d5e3bad96c09bca1d7a2d693c06669aa", - vault: "0x186514400e52270cef3D80e1c6F8d10A75d47344", - }, ]); }); @@ -52,62 +42,59 @@ describe("dataloader", () => { expect(eth_reallocations).toStrictEqual([ { - assets: 1275140484727340602998n, + assets: 1159397680152036107732n, id: "0xb8fc70e82bc5bb53e773626fcc6a23f7eefa036918d7ef216ecfb1950a94a85e", vault: "0x2371e134e3455e0593363cBF89d3b6cf53740618", }, { - assets: 365464355757324173961n, + assets: 334181181282594142674n, id: "0xba761af4134efb0855adfba638945f454f0a704af11fc93439e20c7c5ebab942", vault: "0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658", }, - { - assets: 228469609053469911383n, - id: "0xd0e50cdac92fe2172043f5e0c36532c6369d24947e40968f34a5e8819ca9ec5d", - vault: "0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658", - }, { assets: 213832870661212422340n, id: "0x2287407f0f42ad5ad224f70e4d9da37f02770f79959df703d6cfee8afc548e0d", vault: "0x78Fc2c2eD1A4cDb5402365934aE5648aDAd094d0", }, { - assets: 124911026994913541789n, + assets: 119531849162836164920n, id: "0xcacd4c39af872ddecd48b650557ff5bcc7d3338194c0f5b2038e0d4dec5dc022", vault: "0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658", }, { - assets: 34067768940166463160n, - id: "0x138eec0e4a1937eb92ebc70043ed539661dd7ed5a89fb92a720b341650288a40", + assets: 84374938643006667977n, + id: "0xd0e50cdac92fe2172043f5e0c36532c6369d24947e40968f34a5e8819ca9ec5d", vault: "0x2371e134e3455e0593363cBF89d3b6cf53740618", }, { - assets: 23607619147993488117n, - id: "0x37e7484d642d90f14451f1910ba4b7b8e4c3ccdd0ec28f8b2bdb35479e472ba7", + assets: 66930590311663470057n, + id: "0x0eed5a89c7d397d02fd0b9b8e42811ca67e50ed5aeaa4f22e506516c716cfbbf", vault: "0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658", }, { - assets: 12852204041462170816n, - id: "0xa0534c78620867b7c8706e3b6df9e69a2bc67c783281b7a77e034ed75cee012e", + assets: 23306805022282394159n, + id: "0x698fe98247a40c5771537b5786b2f3f9d78eb487b4ce4d75533cd0e94d88a115", vault: "0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658", }, { - assets: 240388238484242n, - id: "0x87a3e5dbcd822f2a543bea1365b7dd99ad9a1cb460061278319732e63207c792", - vault: "0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658", + assets: 14167222149320089956n, + id: "0x138eec0e4a1937eb92ebc70043ed539661dd7ed5a89fb92a720b341650288a40", + vault: "0x2371e134e3455e0593363cBF89d3b6cf53740618", }, - ]); - expect(usdc_reallocations).toStrictEqual([ { - assets: 2520842846565n, - id: "0xb323495f7e4148be5643a4ea4a8221eef163e4bccfdedc2a6f4696baacbc86cc", - vault: "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", + assets: 10242440491887459673n, + id: "0xa0534c78620867b7c8706e3b6df9e69a2bc67c783281b7a77e034ed75cee012e", + vault: "0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658", }, { - assets: 1511034176993n, - id: "0x64d65c9a2d91c36d56fbc42d69e979335320169b3df63bf92789e2c8883fcc64", - vault: "0xBEEF01735c132Ada46AA9aA4c54623cAA92A64CB", + assets: 348595829549040913n, + id: "0xea023e57814fb9a814a5a9ee9f3e7ece5b771dd8cc703e50b911e9cde064a12d", + vault: "0x4881Ef0BF6d2365D3dd6499ccd7532bcdBCE0658", }, ]); + // At the pinned block, every usdc_wbtc source market already sits at or + // above 90% utilization, so the default 90% withdrawal ceiling (previously + // the API's per-market targetWithdrawUtilization) yields no withdrawals. + expect(usdc_reallocations).toStrictEqual([]); }); }); From 39cfe77780d79040b465d25b8ab3638466ca71c0 Mon Sep 17 00:00:00 2001 From: Foulk plb | Morpho <71005796+Foulks-Plb@users.noreply.github.com> Date: Thu, 23 Jul 2026 17:07:22 +0200 Subject: [PATCH 3/3] test(morpho-sdk): drop the 92% legacy constant, pin parity to the SDK default The withdrawal-utilization default is now always 90%, so the parity harness pins the legacy SimulationState reference onto morpho-sdk's DEFAULT_WITHDRAWAL_TARGET_UTILIZATION (90%) instead of a hardcoded 92% LEGACY_DEFAULT_WITHDRAWAL_UTILIZATION constant. Single source of truth; the comparison stays algorithm-only. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/entities/reallocationData.test.ts | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/packages/morpho-sdk/src/entities/reallocationData.test.ts b/packages/morpho-sdk/src/entities/reallocationData.test.ts index 67ab93e51..d2c1fddc4 100644 --- a/packages/morpho-sdk/src/entities/reallocationData.test.ts +++ b/packages/morpho-sdk/src/entities/reallocationData.test.ts @@ -19,6 +19,7 @@ import { SimulationState as SimulationStateImport } from "@morpho-org/simulation import type { Address } from "viem"; import { maxUint256, zeroAddress } from "viem"; import { describe, expect, test } from "vitest"; +import { DEFAULT_WITHDRAWAL_TARGET_UTILIZATION } from "../helpers/constant.js"; import { DisabledReallocationMarketError, MissingPublicAllocatorConfigError, @@ -36,14 +37,6 @@ const VAULT: Address = "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"; const OTHER_VAULT: Address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; const LOAN_TOKEN: Address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; -/** - * The withdrawal-utilization default used by the legacy `SimulationState` - * reference (92%). `morpho-sdk` now defaults to 90%, so parity cases that omit an - * explicit ceiling pin the new implementation to this legacy value to keep the - * algorithmic comparison exact. - */ -const LEGACY_DEFAULT_WITHDRAWAL_UTILIZATION = 92_0000000000000000n; - type LegacyPublicAllocatorOptions = { readonly enabled?: boolean; readonly reallocatableVaults?: Address[]; @@ -350,7 +343,13 @@ const toLegacyOptions = ( options.reallocatableVaults == null ? undefined : [...options.reallocatableVaults], - defaultMaxWithdrawalUtilization: options.defaultMaxWithdrawalUtilization, + // The legacy `SimulationState` reference defaults its withdrawal ceiling to + // 92% (frozen in `@morpho-org/simulation-sdk`); morpho-sdk now defaults to 90%. + // Pin the reference to the SDK default when a case sets none, so the parity + // comparison stays algorithm-only (not default-driven). + defaultMaxWithdrawalUtilization: + options.defaultMaxWithdrawalUtilization ?? + DEFAULT_WITHDRAWAL_TARGET_UTILIZATION, maxWithdrawalUtilization: options.maxWithdrawalUtilization == null ? undefined @@ -362,12 +361,6 @@ const toReallocationOptions = ( options: PublicAllocatorOptions = {}, ): PublicAllocatorOptions => ({ ...options, - // The legacy reference defaults its withdrawal ceiling to 92%; morpho-sdk now - // defaults to 90%. Pin the new impl to the legacy default when a case sets none - // explicitly, so the parity comparison stays algorithm-only (not default-driven). - defaultMaxWithdrawalUtilization: - options.defaultMaxWithdrawalUtilization ?? - LEGACY_DEFAULT_WITHDRAWAL_UTILIZATION, timestamp: TIMESTAMP, });