@morpho-dev/router 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/cli.js +441 -141
  2. package/dist/drizzle/migrations/0000_setup_single_migration_folder.sql +64 -64
  3. package/dist/drizzle/migrations/0001_add-trigger-for-consumed-events.sql +5 -5
  4. package/dist/drizzle/migrations/0002_insert-status-code.sql +1 -1
  5. package/dist/drizzle/migrations/0003_update-triggers-for-consumed-events.sql +1 -1
  6. package/dist/drizzle/migrations/0004_drop-status-offers-foreign-key-constraint.sql +1 -1
  7. package/dist/drizzle/migrations/0005_add-index-to-boost-group-query-and-offer-hash.sql +1 -1
  8. package/dist/drizzle/migrations/0006_add-callbacks-and-positions-relations.sql +11 -11
  9. package/dist/drizzle/migrations/0008_validation.sql +10 -10
  10. package/dist/drizzle/migrations/0009_add-transfers-table.sql +4 -4
  11. package/dist/drizzle/migrations/0010_add-price.sql +1 -1
  12. package/dist/drizzle/migrations/0011_nullable-callback-amount.sql +1 -1
  13. package/dist/drizzle/migrations/0012_add-position-asset.sql +1 -1
  14. package/dist/drizzle/migrations/0013_remove-depecrated-domains.sql +13 -13
  15. package/dist/drizzle/migrations/0014_rename-offers-v2-into-offers.sql +19 -19
  16. package/dist/drizzle/migrations/0015_add-lots-table.sql +3 -3
  17. package/dist/drizzle/migrations/0016_merkle-metadata.sql +7 -7
  18. package/dist/drizzle/migrations/0017_dusty_the_hunter.sql +1 -1
  19. package/dist/drizzle/migrations/0018_add_chain_collector_constraints.sql +3 -3
  20. package/dist/drizzle/migrations/0019_add-obligation-units-shares.sql +2 -2
  21. package/dist/drizzle/migrations/0020_add-session.sql +1 -1
  22. package/dist/drizzle/migrations/0021_drop_chain_collector_epoch_indexes.sql +2 -2
  23. package/dist/drizzle/migrations/0021_migrate-rate-to-price.sql +6 -6
  24. package/dist/drizzle/migrations/0022_consolidate-price.sql +5 -5
  25. package/dist/drizzle/migrations/0023_remove-block-number-for-collaterals.sql +1 -1
  26. package/dist/drizzle/migrations/0024_add-obligation-id-to-lots.sql +8 -0
  27. package/dist/drizzle/migrations/0025_rename-price-to-tick.sql +202 -0
  28. package/dist/drizzle/migrations/meta/0000_snapshot.json +48 -48
  29. package/dist/drizzle/migrations/meta/0001_snapshot.json +48 -48
  30. package/dist/drizzle/migrations/meta/0002_snapshot.json +48 -48
  31. package/dist/drizzle/migrations/meta/0003_snapshot.json +48 -48
  32. package/dist/drizzle/migrations/meta/0004_snapshot.json +47 -47
  33. package/dist/drizzle/migrations/meta/0005_snapshot.json +47 -47
  34. package/dist/drizzle/migrations/meta/0006_snapshot.json +61 -61
  35. package/dist/drizzle/migrations/meta/0008_snapshot.json +62 -62
  36. package/dist/drizzle/migrations/meta/0009_snapshot.json +66 -66
  37. package/dist/drizzle/migrations/meta/0010_snapshot.json +66 -66
  38. package/dist/drizzle/migrations/meta/0013_snapshot.json +48 -48
  39. package/dist/drizzle/migrations/meta/0014_snapshot.json +48 -48
  40. package/dist/drizzle/migrations/meta/0015_snapshot.json +52 -52
  41. package/dist/drizzle/migrations/meta/0016_snapshot.json +61 -61
  42. package/dist/drizzle/migrations/meta/0017_snapshot.json +61 -61
  43. package/dist/drizzle/migrations/meta/0018_snapshot.json +62 -62
  44. package/dist/drizzle/migrations/meta/0019_snapshot.json +62 -62
  45. package/dist/drizzle/migrations/meta/0023_snapshot.json +62 -62
  46. package/dist/drizzle/migrations/meta/0024_snapshot.json +1448 -0
  47. package/dist/drizzle/migrations/meta/0025_snapshot.json +1448 -0
  48. package/dist/drizzle/migrations/meta/_journal.json +14 -0
  49. package/dist/evm/bytecode/erc20.txt +1 -1
  50. package/dist/evm/bytecode/morpho.txt +1 -1
  51. package/dist/evm/bytecode/multicall3.txt +1 -1
  52. package/dist/evm/bytecode/oracle.txt +1 -1
  53. package/dist/evm/bytecode/vault.txt +1 -1
  54. package/dist/index.browser.d.mts +1157 -81
  55. package/dist/index.browser.d.mts.map +1 -1
  56. package/dist/index.browser.d.ts +1157 -81
  57. package/dist/index.browser.d.ts.map +1 -1
  58. package/dist/index.browser.js +371 -151
  59. package/dist/index.browser.js.map +1 -1
  60. package/dist/index.browser.mjs +366 -152
  61. package/dist/index.browser.mjs.map +1 -1
  62. package/dist/index.node.d.mts +1196 -70
  63. package/dist/index.node.d.mts.map +1 -1
  64. package/dist/index.node.d.ts +1196 -70
  65. package/dist/index.node.d.ts.map +1 -1
  66. package/dist/index.node.js +491 -145
  67. package/dist/index.node.js.map +1 -1
  68. package/dist/index.node.mjs +486 -146
  69. package/dist/index.node.mjs.map +1 -1
  70. package/package.json +1 -1
@@ -11,11 +11,191 @@ import { generateDocument } from "openapi-metadata";
11
11
  import { ApiBody, ApiOperation, ApiParam, ApiProperty, ApiQuery, ApiResponse, ApiTags } from "openapi-metadata/decorators";
12
12
  import createOpenApiFetchClient from "openapi-fetch";
13
13
 
14
+ //#region \0@oxc-project+runtime@0.110.0/helpers/typeof.js
15
+ function _typeof(o) {
16
+ "@babel/helpers - typeof";
17
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
18
+ return typeof o;
19
+ } : function(o) {
20
+ return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
21
+ }, _typeof(o);
22
+ }
23
+
24
+ //#endregion
25
+ //#region \0@oxc-project+runtime@0.110.0/helpers/toPrimitive.js
26
+ function toPrimitive(t, r) {
27
+ if ("object" != _typeof(t) || !t) return t;
28
+ var e = t[Symbol.toPrimitive];
29
+ if (void 0 !== e) {
30
+ var i = e.call(t, r || "default");
31
+ if ("object" != _typeof(i)) return i;
32
+ throw new TypeError("@@toPrimitive must return a primitive value.");
33
+ }
34
+ return ("string" === r ? String : Number)(t);
35
+ }
36
+
37
+ //#endregion
38
+ //#region \0@oxc-project+runtime@0.110.0/helpers/toPropertyKey.js
39
+ function toPropertyKey(t) {
40
+ var i = toPrimitive(t, "string");
41
+ return "symbol" == _typeof(i) ? i : i + "";
42
+ }
43
+
44
+ //#endregion
45
+ //#region \0@oxc-project+runtime@0.110.0/helpers/defineProperty.js
46
+ function _defineProperty(e, r, t) {
47
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
48
+ value: t,
49
+ enumerable: !0,
50
+ configurable: !0,
51
+ writable: !0
52
+ }) : e[r] = t, e;
53
+ }
54
+
55
+ //#endregion
56
+ //#region src/utils/Errors.ts
57
+ var Errors_exports = /* @__PURE__ */ __exportAll({
58
+ BaseError: () => BaseError,
59
+ ReorgError: () => ReorgError
60
+ });
61
+ /**
62
+ * Base error class inherited by all errors thrown by mempool.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * import { Errors } from 'mempool'
67
+ * throw new Errors.BaseError('An error occurred')
68
+ * ```
69
+ */
70
+ var BaseError = class BaseError extends Error {
71
+ constructor(shortMessage, options = {}) {
72
+ const details = (() => {
73
+ if (options.cause instanceof BaseError) {
74
+ if (options.cause.details) return options.cause.details;
75
+ if (options.cause.shortMessage) return options.cause.shortMessage;
76
+ }
77
+ if (options.cause && "details" in options.cause && typeof options.cause.details === "string") return options.cause.details;
78
+ if (options.cause?.message) return options.cause.message;
79
+ return options.details;
80
+ })();
81
+ const message = [
82
+ shortMessage || "An error occurred.",
83
+ ...options.metaMessages ? ["", ...options.metaMessages] : [],
84
+ ...details ? ["", details ? `Details: ${details}` : void 0] : []
85
+ ].filter((x) => typeof x === "string").join("\n");
86
+ super(message, options.cause ? { cause: options.cause } : void 0);
87
+ _defineProperty(this, "details", void 0);
88
+ _defineProperty(this, "shortMessage", void 0);
89
+ _defineProperty(this, "cause", void 0);
90
+ _defineProperty(this, "name", "BaseError");
91
+ this.cause = options.cause;
92
+ this.details = details;
93
+ this.shortMessage = shortMessage;
94
+ }
95
+ walk(fn) {
96
+ return walk(this, fn);
97
+ }
98
+ };
99
+ /** @internal */
100
+ function walk(err, fn) {
101
+ if (fn?.(err)) return err;
102
+ if (err && typeof err === "object" && "cause" in err && err.cause) return walk(err.cause, fn);
103
+ return fn ? null : err;
104
+ }
105
+ var ReorgError = class extends BaseError {
106
+ constructor(blockNumber) {
107
+ super(`Reorg detected at block number ${blockNumber}`);
108
+ _defineProperty(this, "name", "ReorgError");
109
+ }
110
+ };
111
+
112
+ //#endregion
113
+ //#region src/core/Tick.ts
114
+ var Tick_exports = /* @__PURE__ */ __exportAll({
115
+ InvalidPriceError: () => InvalidPriceError,
116
+ InvalidTickError: () => InvalidTickError,
117
+ MAX_PRICE: () => MAX_PRICE,
118
+ TICK_RANGE: () => TICK_RANGE,
119
+ priceToTick: () => priceToTick,
120
+ tickToPrice: () => tickToPrice
121
+ });
122
+ /** ln(1 + 0.025), scaled by 1e18. Matches TickLib onchain constant. */
123
+ const LN_ONE_PLUS_DELTA = 24692612590371501n;
124
+ /** ln(2), scaled by 1e18. Matches TickLib onchain constant. */
125
+ const LN2 = 693147180559945309n;
126
+ const WAD$1 = 10n ** 18n;
127
+ const WAD_SQUARED = 10n ** 36n;
128
+ const PRICE_STEP = 10n ** 13n;
129
+ const HALF_TICK_RANGE = 495n;
130
+ /** Tick domain supported by Morpho V2. */
131
+ const TICK_RANGE = 990;
132
+ /** Max allowed price (1e18 in wad). */
133
+ const MAX_PRICE = WAD$1;
134
+ /**
135
+ * Converts a tick to a wad price using the same approximation and rounding as TickLib.
136
+ * @param tick - Tick value in the inclusive range [0, 990].
137
+ * @returns The price in wad units.
138
+ * @throws {@link InvalidTickError} If tick is not an integer in range [0, 990].
139
+ */
140
+ function tickToPrice(tick) {
141
+ assertTick(tick);
142
+ return divHalfDownUnchecked(divHalfDownUnchecked(WAD_SQUARED, WAD$1 + wExp(LN_ONE_PLUS_DELTA * (HALF_TICK_RANGE - BigInt(tick)))), PRICE_STEP) * PRICE_STEP;
143
+ }
144
+ /**
145
+ * Returns the lowest tick with a higher-or-equal price.
146
+ * @param price - Price in wad units.
147
+ * @returns The first tick whose {@link tickToPrice} is greater than or equal to `price`.
148
+ * @throws {@link InvalidPriceError} If price is outside [0, 1e18].
149
+ */
150
+ function priceToTick(price) {
151
+ assertPrice(price);
152
+ let low = 0;
153
+ let high = TICK_RANGE;
154
+ while (low !== high) {
155
+ const mid = Math.floor((low + high) / 2);
156
+ if (tickToPrice(mid) < price) low = mid + 1;
157
+ else high = mid;
158
+ }
159
+ return low;
160
+ }
161
+ function divHalfDownUnchecked(x, d) {
162
+ return (x + (d - 1n) / 2n) / d;
163
+ }
164
+ function wExp(x) {
165
+ if (x < 0n) return WAD_SQUARED / wExp(-x);
166
+ const q = (x + LN2 / 2n) / LN2;
167
+ const r = x - q * LN2;
168
+ const secondTerm = r * r / (2n * WAD$1);
169
+ const thirdTerm = secondTerm * r / (3n * WAD$1);
170
+ return WAD$1 + r + secondTerm + thirdTerm << q;
171
+ }
172
+ function assertTick(tick) {
173
+ if (!Number.isInteger(tick) || tick < 0 || tick > TICK_RANGE) throw new InvalidTickError(tick);
174
+ }
175
+ function assertPrice(price) {
176
+ if (price < 0n || price > MAX_PRICE) throw new InvalidPriceError(price);
177
+ }
178
+ var InvalidTickError = class extends BaseError {
179
+ constructor(tick) {
180
+ super(`Invalid tick: ${tick}. Tick must be an integer between 0 and ${TICK_RANGE}.`);
181
+ _defineProperty(this, "name", "Tick.InvalidTickError");
182
+ }
183
+ };
184
+ var InvalidPriceError = class extends BaseError {
185
+ constructor(price) {
186
+ super(`Invalid price: ${price}. Price must be between 0 and ${MAX_PRICE}.`);
187
+ _defineProperty(this, "name", "Tick.InvalidPriceError");
188
+ }
189
+ };
190
+
191
+ //#endregion
14
192
  //#region src/api/Schema/BookResponse.ts
15
193
  var BookResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$15 });
16
194
  function from$15(level) {
195
+ const price = tickToPrice(level.tick);
17
196
  return {
18
- price: level.price.toString(),
197
+ tick: level.tick,
198
+ price: price.toString(),
19
199
  assets: level.assets.toString(),
20
200
  count: level.count
21
201
  };
@@ -98,6 +278,61 @@ const MetaMorpho = parseAbi([
98
278
  //#region src/core/Abi/MetaMorphoFactory.ts
99
279
  const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed metaMorpho,address indexed caller,address initialOwner,uint256 initialTimelock,address indexed asset,string name,string symbol,bytes32 salt)", "function isMetaMorpho(address) view returns (bool)"]);
100
280
 
281
+ //#endregion
282
+ //#region src/core/Abi/MorphoV2.ts
283
+ const MorphoV2 = parseAbi([
284
+ "constructor()",
285
+ "function collateralOf(bytes32 id, address user, address collateralToken) view returns (uint256)",
286
+ "function consume(bytes32 group, uint256 amount)",
287
+ "function consumed(address user, bytes32 group) view returns (uint256)",
288
+ "function debtOf(bytes32 id, address user) view returns (uint256)",
289
+ "function defaultFees(address loanToken, uint256 index) view returns (uint16)",
290
+ "function feeSetter() view returns (address)",
291
+ "function fees(bytes32 id) view returns (uint16[6])",
292
+ "function flashLoan(address token, uint256 assets, address callback, bytes data)",
293
+ "function isHealthy((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bytes32 id, address borrower) view returns (bool)",
294
+ "function liquidate((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, (uint256 collateralIndex, uint256 repaid, uint256 seized)[] seizures, address borrower, bytes data) returns ((uint256 collateralIndex, uint256 repaid, uint256 seized)[])",
295
+ "function multicall(bytes[] calls)",
296
+ "function obligationCreated(bytes32 id) view returns (bool)",
297
+ "function obligationState(bytes32 id) view returns (uint128 totalUnits, uint128 totalShares, uint256 withdrawable, bool created)",
298
+ "function owner() view returns (address)",
299
+ "function repay((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, address onBehalf)",
300
+ "function session(address user) view returns (bytes32)",
301
+ "function setDefaultTradingFee(address loanToken, uint256 index, uint256 newTradingFee)",
302
+ "function setFeeSetter(address newFeeSetter)",
303
+ "function setObligationTradingFee(bytes32 id, uint256 index, uint256 newTradingFee)",
304
+ "function setOwner(address newOwner)",
305
+ "function setTradingFeeRecipient(address recipient)",
306
+ "function sharesOf(bytes32 id, address user) view returns (uint256)",
307
+ "function shuffleSession()",
308
+ "function supplyCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, address collateral, uint256 assets, address onBehalf)",
309
+ "function take(uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, address taker, ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bool buy, address maker, uint256 assets, uint256 obligationUnits, uint256 obligationShares, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof, address takerCallback, bytes takerCallbackData) returns (uint256, uint256, uint256, uint256)",
310
+ "function totalShares(bytes32 id) view returns (uint256)",
311
+ "function totalUnits(bytes32 id) view returns (uint256)",
312
+ "function touchObligation((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation) returns (bytes32)",
313
+ "function tradingFee(bytes32 id, uint256 timeToMaturity) view returns (uint256)",
314
+ "function tradingFeeRecipient() view returns (address)",
315
+ "function withdraw((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, uint256 shares, address onBehalf) returns (uint256, uint256)",
316
+ "function withdrawCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, address collateral, uint256 assets, address onBehalf)",
317
+ "function withdrawable(bytes32 id) view returns (uint256)",
318
+ "event Constructor(address indexed owner)",
319
+ "event Consume(address indexed user, bytes32 indexed group, uint256 amount)",
320
+ "event FlashLoan(address indexed caller, address indexed token, uint256 assets)",
321
+ "event Liquidate(address indexed caller, bytes32 indexed id, (uint256 collateralIndex, uint256 repaid, uint256 seized)[] seizures, address indexed borrower, uint256 totalRepaid, uint256 badDebt)",
322
+ "event ObligationCreated(bytes32 indexed id, (address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation)",
323
+ "event Repay(address indexed caller, bytes32 indexed id, uint256 obligationUnits, address indexed onBehalf)",
324
+ "event SetDefaultTradingFee(address indexed loanToken, uint256 indexed index, uint256 newTradingFee)",
325
+ "event SetFeeSetter(address indexed feeSetter)",
326
+ "event SetObligationTradingFee(bytes32 indexed id, uint256 indexed index, uint256 newTradingFee)",
327
+ "event SetOwner(address indexed owner)",
328
+ "event SetTradingFeeRecipient(address indexed recipient)",
329
+ "event ShuffleSession(address indexed user, bytes32 session)",
330
+ "event SupplyCollateral(address caller, bytes32 indexed id, address indexed collateral, uint256 assets, address indexed onBehalf)",
331
+ "event Take(address caller, bytes32 indexed id, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, bool buyerIsLender, bool sellerIsBorrower, bytes32 group, uint256 consumed)",
332
+ "event Withdraw(address indexed caller, bytes32 indexed id, uint256 obligationUnits, uint256 shares, address indexed onBehalf)",
333
+ "event WithdrawCollateral(address caller, bytes32 indexed id, address indexed collateral, uint256 assets, address indexed onBehalf)"
334
+ ]);
335
+
101
336
  //#endregion
102
337
  //#region src/core/Abi/index.ts
103
338
  var Abi_exports = /* @__PURE__ */ __exportAll({
@@ -105,6 +340,7 @@ var Abi_exports = /* @__PURE__ */ __exportAll({
105
340
  MetaMorpho: () => MetaMorpho,
106
341
  MetaMorphoFactory: () => MetaMorphoFactory,
107
342
  Morpho: () => Morpho,
343
+ MorphoV2: () => MorphoV2,
108
344
  Oracle: () => Oracle
109
345
  });
110
346
  const Oracle = [{
@@ -307,105 +543,6 @@ function* batch$1(array, batchSize) {
307
543
  for (let i = 0; i < array.length; i += batchSize) yield array.slice(i, i + batchSize);
308
544
  }
309
545
 
310
- //#endregion
311
- //#region \0@oxc-project+runtime@0.110.0/helpers/typeof.js
312
- function _typeof(o) {
313
- "@babel/helpers - typeof";
314
- return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
315
- return typeof o;
316
- } : function(o) {
317
- return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
318
- }, _typeof(o);
319
- }
320
-
321
- //#endregion
322
- //#region \0@oxc-project+runtime@0.110.0/helpers/toPrimitive.js
323
- function toPrimitive(t, r) {
324
- if ("object" != _typeof(t) || !t) return t;
325
- var e = t[Symbol.toPrimitive];
326
- if (void 0 !== e) {
327
- var i = e.call(t, r || "default");
328
- if ("object" != _typeof(i)) return i;
329
- throw new TypeError("@@toPrimitive must return a primitive value.");
330
- }
331
- return ("string" === r ? String : Number)(t);
332
- }
333
-
334
- //#endregion
335
- //#region \0@oxc-project+runtime@0.110.0/helpers/toPropertyKey.js
336
- function toPropertyKey(t) {
337
- var i = toPrimitive(t, "string");
338
- return "symbol" == _typeof(i) ? i : i + "";
339
- }
340
-
341
- //#endregion
342
- //#region \0@oxc-project+runtime@0.110.0/helpers/defineProperty.js
343
- function _defineProperty(e, r, t) {
344
- return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
345
- value: t,
346
- enumerable: !0,
347
- configurable: !0,
348
- writable: !0
349
- }) : e[r] = t, e;
350
- }
351
-
352
- //#endregion
353
- //#region src/utils/Errors.ts
354
- var Errors_exports = /* @__PURE__ */ __exportAll({
355
- BaseError: () => BaseError,
356
- ReorgError: () => ReorgError
357
- });
358
- /**
359
- * Base error class inherited by all errors thrown by mempool.
360
- *
361
- * @example
362
- * ```ts
363
- * import { Errors } from 'mempool'
364
- * throw new Errors.BaseError('An error occurred')
365
- * ```
366
- */
367
- var BaseError = class BaseError extends Error {
368
- constructor(shortMessage, options = {}) {
369
- const details = (() => {
370
- if (options.cause instanceof BaseError) {
371
- if (options.cause.details) return options.cause.details;
372
- if (options.cause.shortMessage) return options.cause.shortMessage;
373
- }
374
- if (options.cause && "details" in options.cause && typeof options.cause.details === "string") return options.cause.details;
375
- if (options.cause?.message) return options.cause.message;
376
- return options.details;
377
- })();
378
- const message = [
379
- shortMessage || "An error occurred.",
380
- ...options.metaMessages ? ["", ...options.metaMessages] : [],
381
- ...details ? ["", details ? `Details: ${details}` : void 0] : []
382
- ].filter((x) => typeof x === "string").join("\n");
383
- super(message, options.cause ? { cause: options.cause } : void 0);
384
- _defineProperty(this, "details", void 0);
385
- _defineProperty(this, "shortMessage", void 0);
386
- _defineProperty(this, "cause", void 0);
387
- _defineProperty(this, "name", "BaseError");
388
- this.cause = options.cause;
389
- this.details = details;
390
- this.shortMessage = shortMessage;
391
- }
392
- walk(fn) {
393
- return walk(this, fn);
394
- }
395
- };
396
- /** @internal */
397
- function walk(err, fn) {
398
- if (fn?.(err)) return err;
399
- if (err && typeof err === "object" && "cause" in err && err.cause) return walk(err.cause, fn);
400
- return fn ? null : err;
401
- }
402
- var ReorgError = class extends BaseError {
403
- constructor(blockNumber) {
404
- super(`Reorg detected at block number ${blockNumber}`);
405
- _defineProperty(this, "name", "ReorgError");
406
- }
407
- };
408
-
409
546
  //#endregion
410
547
  //#region src/core/Chain.ts
411
548
  var Chain_exports = /* @__PURE__ */ __exportAll({
@@ -510,8 +647,8 @@ const chains$1 = {
510
647
  name: "ethereum-virtual-testnet",
511
648
  custom: {
512
649
  morpho: {
513
- address: "0x11a002d45db720ed47a80d2f3489cba5b833eaf5",
514
- blockCreated: 0
650
+ address: "0x634b095371e4e45feed94c1a45c37798e173ea50",
651
+ blockCreated: 23226700
515
652
  },
516
653
  morphoBlue: {
517
654
  address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
@@ -1452,7 +1589,7 @@ const OfferSchema = () => {
1452
1589
  assets: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
1453
1590
  obligationUnits: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
1454
1591
  obligationShares: z$1.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
1455
- price: z$1.bigint({ coerce: true }).min(0n).max(maxUint256),
1592
+ tick: z$1.coerce.number().int().min(0).max(990),
1456
1593
  maturity: MaturitySchema,
1457
1594
  expiry: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
1458
1595
  start: z$1.number().int().max(Number.MAX_SAFE_INTEGER),
@@ -1524,7 +1661,7 @@ const serialize = (offer) => ({
1524
1661
  assets: offer.assets.toString(),
1525
1662
  obligationUnits: offer.obligationUnits.toString(),
1526
1663
  obligationShares: offer.obligationShares.toString(),
1527
- price: offer.price.toString(),
1664
+ tick: offer.tick,
1528
1665
  maturity: Number(offer.maturity),
1529
1666
  expiry: Number(offer.expiry),
1530
1667
  start: Number(offer.start),
@@ -1569,14 +1706,13 @@ function random$1(config) {
1569
1706
  [.98, 2]
1570
1707
  ]));
1571
1708
  const buy = config?.buy !== void 0 ? config.buy : bool();
1572
- const ONE = 1000000000000000000n;
1573
- const qMin = buy ? 16 : 4;
1574
- const len = (buy ? 32 : 16) - qMin + 1;
1575
- const pricePairs = Array.from({ length: len }, (_, idx) => {
1576
- const q = qMin + idx;
1577
- return [BigInt(q) * (ONE / 4n), buy ? 1 + idx : 1 + (len - 1 - idx)];
1709
+ const tickMin = buy ? 0 : 495;
1710
+ const len = (buy ? 495 : 990) - tickMin + 1;
1711
+ const tickPairs = Array.from({ length: len }, (_, idx) => {
1712
+ const weight = buy ? 1 + idx : 1 + (len - 1 - idx);
1713
+ return [tickMin + idx, weight];
1578
1714
  });
1579
- const price = config?.price ?? weightedChoice(pricePairs);
1715
+ const tick = config?.tick ?? weightedChoice(tickPairs);
1580
1716
  const loanTokenDecimals = config?.assetsDecimals?.[loanToken] ?? 18;
1581
1717
  const unit = BigInt(10) ** BigInt(loanTokenDecimals);
1582
1718
  const amountBase = BigInt(100 + int(999901));
@@ -1590,7 +1726,7 @@ function random$1(config) {
1590
1726
  assets: assetsScaled,
1591
1727
  obligationUnits: config?.obligationUnits ?? 0n,
1592
1728
  obligationShares: config?.obligationShares ?? 0n,
1593
- price,
1729
+ tick,
1594
1730
  maturity,
1595
1731
  expiry: config?.expiry ?? maturity - 1,
1596
1732
  start: config?.start ?? maturity - 10,
@@ -1655,7 +1791,7 @@ const types = {
1655
1791
  type: "uint256"
1656
1792
  },
1657
1793
  {
1658
- name: "price",
1794
+ name: "tick",
1659
1795
  type: "uint256"
1660
1796
  },
1661
1797
  {
@@ -1723,7 +1859,7 @@ function hash(offer) {
1723
1859
  assets: offer.assets,
1724
1860
  obligationUnits: offer.obligationUnits,
1725
1861
  obligationShares: offer.obligationShares,
1726
- price: offer.price,
1862
+ tick: BigInt(offer.tick),
1727
1863
  maturity: BigInt(offer.maturity),
1728
1864
  expiry: BigInt(offer.expiry),
1729
1865
  group: offer.group,
@@ -1774,7 +1910,7 @@ const OfferAbi = [
1774
1910
  type: "uint256"
1775
1911
  },
1776
1912
  {
1777
- name: "price",
1913
+ name: "tick",
1778
1914
  type: "uint256"
1779
1915
  },
1780
1916
  {
@@ -1845,7 +1981,7 @@ function encode$1(offer) {
1845
1981
  offer.assets,
1846
1982
  offer.obligationUnits,
1847
1983
  offer.obligationShares,
1848
- offer.price,
1984
+ BigInt(offer.tick),
1849
1985
  BigInt(offer.maturity),
1850
1986
  BigInt(offer.expiry),
1851
1987
  offer.group,
@@ -1870,7 +2006,7 @@ function decode$1(data) {
1870
2006
  assets: decoded[1],
1871
2007
  obligationUnits: decoded[2],
1872
2008
  obligationShares: decoded[3],
1873
- price: decoded[4],
2009
+ tick: Number(decoded[4]),
1874
2010
  maturity: from$11(Number(decoded[5])),
1875
2011
  expiry: Number(decoded[6]),
1876
2012
  group: decoded[7],
@@ -2734,6 +2870,16 @@ const BrandTypeId = Symbol.for("mempool/Brand");
2734
2870
  //#endregion
2735
2871
  //#region src/api/Schema/OfferResponse.ts
2736
2872
  var OfferResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$2 });
2873
+ function normalizeChainId(chainId) {
2874
+ const parsedChainId = Number(chainId);
2875
+ if (!Number.isInteger(parsedChainId) || parsedChainId <= 0) throw new Error(`Invalid chain id: ${String(chainId)}`);
2876
+ return parsedChainId;
2877
+ }
2878
+ function normalizeBlockNumber(blockNumber) {
2879
+ const parsedBlockNumber = Number(blockNumber);
2880
+ if (!Number.isInteger(parsedBlockNumber) || parsedBlockNumber < 0) throw new Error(`Invalid block number: ${String(blockNumber)}`);
2881
+ return parsedBlockNumber;
2882
+ }
2737
2883
  /**
2738
2884
  * Creates an `OfferResponse` matching the Solidity Offer struct layout.
2739
2885
  * @constructor
@@ -2741,6 +2887,8 @@ var OfferResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$2 });
2741
2887
  * @returns The created `OfferResponse`. {@link OfferResponse}
2742
2888
  */
2743
2889
  function from$2(input) {
2890
+ const chainId = normalizeChainId(input.chainId);
2891
+ const blockNumber = normalizeBlockNumber(input.blockNumber);
2744
2892
  const base = {
2745
2893
  offer: {
2746
2894
  obligation: {
@@ -2759,7 +2907,7 @@ function from$2(input) {
2759
2907
  obligation_shares: input.obligationShares.toString(),
2760
2908
  start: input.start,
2761
2909
  expiry: input.expiry,
2762
- price: input.price.toString(),
2910
+ tick: input.tick,
2763
2911
  group: input.group,
2764
2912
  session: input.session,
2765
2913
  callback: input.callback.address,
@@ -2767,15 +2915,15 @@ function from$2(input) {
2767
2915
  },
2768
2916
  offer_hash: input.hash,
2769
2917
  obligation_id: id({
2770
- chainId: input.chainId,
2918
+ chainId,
2771
2919
  loanToken: input.loanToken,
2772
2920
  collaterals: [...input.collaterals],
2773
2921
  maturity: input.maturity
2774
2922
  }),
2775
- chain_id: input.chainId,
2923
+ chain_id: chainId,
2776
2924
  consumed: input.consumed.toString(),
2777
2925
  takeable: input.takeable.toString(),
2778
- block_number: input.blockNumber
2926
+ block_number: blockNumber
2779
2927
  };
2780
2928
  if (!input.proof || !input.root || !input.signature) return {
2781
2929
  ...base,
@@ -2832,7 +2980,7 @@ const offerExample = {
2832
2980
  obligation_shares: "0",
2833
2981
  start: 1761922790,
2834
2982
  expiry: 1761922799,
2835
- price: "2750000000000000000",
2983
+ tick: 495,
2836
2984
  group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
2837
2985
  session: "0x0000000000000000000000000000000000000000000000000000000000000000",
2838
2986
  callback: "0x0000000000000000000000000000000000000000",
@@ -2873,7 +3021,7 @@ const validateOfferExample = {
2873
3021
  assets: "369216000000000000000000",
2874
3022
  obligation_units: "0",
2875
3023
  obligation_shares: "0",
2876
- price: "2750000000000000000",
3024
+ tick: 495,
2877
3025
  maturity: 1761922799,
2878
3026
  expiry: 1761922799,
2879
3027
  start: 1761922790,
@@ -3017,9 +3165,11 @@ __decorate([ApiProperty({
3017
3165
  example: offerExample.offer.expiry
3018
3166
  })], OfferDataResponse.prototype, "expiry", void 0);
3019
3167
  __decorate([ApiProperty({
3020
- type: "string",
3021
- example: offerExample.offer.price
3022
- })], OfferDataResponse.prototype, "price", void 0);
3168
+ type: "number",
3169
+ example: offerExample.offer.tick,
3170
+ minimum: 0,
3171
+ maximum: 990
3172
+ })], OfferDataResponse.prototype, "tick", void 0);
3023
3173
  __decorate([ApiProperty({
3024
3174
  type: "string",
3025
3175
  example: offerExample.offer.group
@@ -3260,9 +3410,11 @@ __decorate([ApiProperty({
3260
3410
  required: false
3261
3411
  })], ValidateOfferRequest.prototype, "obligation_shares", void 0);
3262
3412
  __decorate([ApiProperty({
3263
- type: "string",
3264
- example: validateOfferExample.price
3265
- })], ValidateOfferRequest.prototype, "price", void 0);
3413
+ type: "number",
3414
+ example: validateOfferExample.tick,
3415
+ minimum: 0,
3416
+ maximum: 990
3417
+ })], ValidateOfferRequest.prototype, "tick", void 0);
3266
3418
  __decorate([ApiProperty({
3267
3419
  type: "number",
3268
3420
  example: validateOfferExample.maturity
@@ -3362,9 +3514,16 @@ __decorate([ApiProperty({
3362
3514
  description: "List of validation issues. Returned when any offer fails validation."
3363
3515
  })], ValidationFailureResponse.prototype, "data", void 0);
3364
3516
  var BookLevelResponse = class {};
3517
+ __decorate([ApiProperty({
3518
+ type: "number",
3519
+ example: 495,
3520
+ minimum: 0,
3521
+ maximum: 990
3522
+ })], BookLevelResponse.prototype, "tick", void 0);
3365
3523
  __decorate([ApiProperty({
3366
3524
  type: "string",
3367
- example: "2750000000000000000"
3525
+ example: "500000000000000000",
3526
+ description: "Price derived from tick, scaled by 1e18."
3368
3527
  })], BookLevelResponse.prototype, "price", void 0);
3369
3528
  __decorate([ApiProperty({
3370
3529
  type: "string",
@@ -3378,6 +3537,7 @@ const positionExample = {
3378
3537
  chain_id: 1,
3379
3538
  contract: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
3380
3539
  user: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
3540
+ obligation_id: "0x12590ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9f67",
3381
3541
  reserved: "200000000000000000000",
3382
3542
  block_number: 21345678
3383
3543
  };
@@ -3394,6 +3554,12 @@ __decorate([ApiProperty({
3394
3554
  type: "string",
3395
3555
  example: positionExample.user
3396
3556
  })], PositionListItemResponse.prototype, "user", void 0);
3557
+ __decorate([ApiProperty({
3558
+ type: "string",
3559
+ nullable: true,
3560
+ example: positionExample.obligation_id,
3561
+ description: "Obligation id this reserved amount belongs to, or null if no lots exist."
3562
+ })], PositionListItemResponse.prototype, "obligation_id", void 0);
3397
3563
  __decorate([ApiProperty({
3398
3564
  type: "string",
3399
3565
  example: positionExample.reserved
@@ -3421,7 +3587,7 @@ __decorate([ApiProperty({
3421
3587
  })], BookListResponse.prototype, "cursor", void 0);
3422
3588
  __decorate([ApiProperty({
3423
3589
  type: () => [BookLevelResponse],
3424
- description: "Aggregated book levels grouped by computed price."
3590
+ description: "Aggregated book levels grouped by offer tick."
3425
3591
  })], BookListResponse.prototype, "data", void 0);
3426
3592
  let BooksController = class BooksController {
3427
3593
  async getBook() {}
@@ -3431,7 +3597,7 @@ __decorate([
3431
3597
  methods: ["get"],
3432
3598
  path: "/v1/books/{obligationId}/{side}",
3433
3599
  summary: "Get aggregated book",
3434
- description: "Returns aggregated book data for a given obligation and side. Offers are grouped by computed price with summed takeable amounts. Book levels are sorted by price (ascending for buy side, descending for sell side)."
3600
+ description: "Returns aggregated book data for a given obligation and side. Offers are grouped by tick with summed takeable amounts, and each level includes the corresponding wad-scaled price. Book levels are sorted by tick (ascending for sell side, descending for buy side)."
3435
3601
  }),
3436
3602
  ApiParam({
3437
3603
  name: "obligationId",
@@ -3456,7 +3622,7 @@ __decorate([
3456
3622
  name: "limit",
3457
3623
  type: "number",
3458
3624
  example: 10,
3459
- description: "Maximum number of price levels to return."
3625
+ description: "Maximum number of tick levels to return."
3460
3626
  }),
3461
3627
  ApiResponse({
3462
3628
  status: 200,
@@ -3650,6 +3816,11 @@ const configRulesLoanTokenExample = {
3650
3816
  chain_id: 1,
3651
3817
  address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
3652
3818
  };
3819
+ const configRulesCollateralTokenExample = {
3820
+ type: "collateral_token",
3821
+ chain_id: 1,
3822
+ address: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
3823
+ };
3653
3824
  const configRulesOracleExample = {
3654
3825
  type: "oracle",
3655
3826
  chain_id: 1,
@@ -3659,6 +3830,7 @@ const configRulesChecksumExample = "f1d2d2f924e986ac86fdf7b36c94bcdf";
3659
3830
  const configRulesPayloadExample = [
3660
3831
  configRulesMaturityExample,
3661
3832
  configRulesLoanTokenExample,
3833
+ configRulesCollateralTokenExample,
3662
3834
  configRulesOracleExample
3663
3835
  ];
3664
3836
  const configContractNames = [
@@ -3785,7 +3957,7 @@ __decorate([
3785
3957
  methods: ["get"],
3786
3958
  path: "/v1/config/rules",
3787
3959
  summary: "Get config rules",
3788
- description: "Returns configured rules (maturities, loan tokens, oracles) for supported chains."
3960
+ description: "Returns configured rules (maturities, loan tokens, collateral tokens, oracles) for supported chains."
3789
3961
  }),
3790
3962
  ApiQuery({
3791
3963
  name: "cursor",
@@ -3805,7 +3977,7 @@ __decorate([
3805
3977
  name: "types",
3806
3978
  type: ["string"],
3807
3979
  required: false,
3808
- example: "maturity,loan_token,oracle",
3980
+ example: "maturity,loan_token,collateral_token,oracle",
3809
3981
  description: "Filter by rule types (comma-separated).",
3810
3982
  style: "form",
3811
3983
  explode: false
@@ -3923,7 +4095,7 @@ __decorate([
3923
4095
  methods: ["get"],
3924
4096
  path: "/v1/users/{userAddress}/positions",
3925
4097
  summary: "Get user positions",
3926
- description: "Returns positions for a user with reserved balance. The reserved balance is the amount locked by active offers (max lot upper - offset - consumed)."
4098
+ description: "Returns positions for a user with reserved balance per obligation. Each (position, obligation) pair is returned as a separate row. Positions with no lots return a single row with obligation_id = null and reserved = 0."
3927
4099
  }),
3928
4100
  ApiParam({
3929
4101
  name: "userAddress",
@@ -4011,6 +4183,7 @@ function from$1(position) {
4011
4183
  chain_id: position.chainId,
4012
4184
  contract: position.contract,
4013
4185
  user: position.user,
4186
+ obligation_id: position.obligationId,
4014
4187
  reserved: position.reserved.toString(),
4015
4188
  block_number: position.blockNumber
4016
4189
  };
@@ -4064,10 +4237,11 @@ const ConfigRuleTypes = z$1.enum([
4064
4237
  "maturity",
4065
4238
  "callback",
4066
4239
  "loan_token",
4240
+ "collateral_token",
4067
4241
  "oracle"
4068
4242
  ]);
4069
4243
  const GetConfigRulesQueryParams = z$1.object({
4070
- cursor: z$1.string().regex(/^(maturity|callback|loan_token|oracle):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
4244
+ cursor: z$1.string().regex(/^(maturity|callback|loan_token|collateral_token|oracle):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
4071
4245
  description: "Pagination cursor in type:chain_id:<value> format",
4072
4246
  example: "maturity:1:1730415600:end_of_next_month"
4073
4247
  }),
@@ -4077,7 +4251,7 @@ const GetConfigRulesQueryParams = z$1.object({
4077
4251
  }),
4078
4252
  types: csvArray(ConfigRuleTypes).meta({
4079
4253
  description: "Filter by rule types (comma-separated).",
4080
- example: "maturity,loan_token,oracle"
4254
+ example: "maturity,loan_token,collateral_token,oracle"
4081
4255
  }),
4082
4256
  chains: csvArray(z$1.string().regex(/^[1-9]\d*$/, { message: "Chain must be a positive integer" }).transform((val) => Number.parseInt(val, 10))).meta({
4083
4257
  description: "Filter by chain IDs (comma-separated).",
@@ -4177,12 +4351,11 @@ const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obl
4177
4351
  description: "Obligation id",
4178
4352
  example: "0x1234567890123456789012345678901234567890123456789012345678901234"
4179
4353
  }) });
4180
- /** Validate a book cursor format: {side, lastPrice, offersCursor} */
4354
+ /** Validate a book cursor format: {side, lastTick, offersCursor} */
4181
4355
  function isValidBookCursor(cursorString) {
4182
- const isNumericString = (value) => typeof value === "string" && /^-?\d+$/.test(value);
4183
4356
  try {
4184
4357
  const v = JSON.parse(Buffer.from(cursorString, "base64url").toString("utf8"));
4185
- return (v?.side === "buy" || v?.side === "sell") && isNumericString(v?.lastPrice) && (v?.offersCursor === null || typeof v?.offersCursor === "string");
4358
+ return (v?.side === "buy" || v?.side === "sell") && typeof v?.lastTick === "number" && Number.isInteger(v.lastTick) && (v?.offersCursor === null || typeof v?.offersCursor === "string");
4186
4359
  } catch {
4187
4360
  return false;
4188
4361
  }
@@ -4343,7 +4516,7 @@ async function getOffers(apiClient, parameters) {
4343
4516
  assets: offerData.assets,
4344
4517
  obligation_units: offerData.obligation_units,
4345
4518
  obligation_shares: offerData.obligation_shares,
4346
- price: offerData.price,
4519
+ tick: offerData.tick,
4347
4520
  maturity: from$11(offerData.obligation.maturity),
4348
4521
  expiry: offerData.expiry,
4349
4522
  start: offerData.start,
@@ -4691,6 +4864,33 @@ const assets = {
4691
4864
  "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"
4692
4865
  ]
4693
4866
  };
4867
+ const collateralAssets = {
4868
+ [ChainId.ETHEREUM.toString()]: [
4869
+ "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
4870
+ "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
4871
+ "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
4872
+ "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
4873
+ ],
4874
+ [ChainId.BASE.toString()]: [
4875
+ "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
4876
+ "0x4200000000000000000000000000000000000006",
4877
+ "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
4878
+ "0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
4879
+ "0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42"
4880
+ ],
4881
+ [ChainId["ETHEREUM-VIRTUAL-TESTNET"].toString()]: [
4882
+ "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
4883
+ "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
4884
+ "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
4885
+ "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
4886
+ ],
4887
+ [ChainId.ANVIL.toString()]: [
4888
+ "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
4889
+ "0x1aBaEA1f7C830bD89Acc67eC4af516284b1bC33c",
4890
+ "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
4891
+ "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
4892
+ ]
4893
+ };
4694
4894
  const oracles = {
4695
4895
  [ChainId.ETHEREUM.toString()]: [
4696
4896
  "0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
@@ -4753,10 +4953,11 @@ var Rules_exports = /* @__PURE__ */ __exportAll({
4753
4953
  amountMutualExclusivity: () => amountMutualExclusivity,
4754
4954
  callback: () => callback,
4755
4955
  chains: () => chains,
4956
+ collateralToken: () => collateralToken,
4957
+ loanToken: () => loanToken,
4756
4958
  maturity: () => maturity,
4757
4959
  oracle: () => oracle,
4758
4960
  sameMaker: () => sameMaker,
4759
- token: () => token,
4760
4961
  validity: () => validity
4761
4962
  });
4762
4963
  /**
@@ -4784,15 +4985,25 @@ const callback = ({ callbacks }) => single("callback", `Validates callbacks: buy
4784
4985
  if (isEmptyCallback(offer) && !offer.buy && !callbacks.includes(Type$1.SellWithEmptyCallback)) return { message: "Sell offers with empty callback not allowed." };
4785
4986
  });
4786
4987
  /**
4787
- * A validation rule that checks if the offer's tokens are allowed for its chain.
4788
- * @param assetsByChainId - Allowed assets indexed by chain id.
4988
+ * A validation rule that checks if the offer's loan token is allowed for its chain.
4989
+ * @param assetsByChainId - Allowed loan tokens indexed by chain id.
4990
+ * @returns The issue that was found. If the offer is valid, this will be undefined.
4991
+ */
4992
+ const loanToken = ({ assetsByChainId }) => single("loan_token", "Validates that offer loan token is in the allowed token list for the offer chain", (offer) => {
4993
+ const allowedLoanTokens = assetsByChainId[offer.chainId]?.map((asset) => asset.toLowerCase());
4994
+ if (!allowedLoanTokens || allowedLoanTokens.length === 0) return { message: `No allowed loan tokens for chain ${offer.chainId}` };
4995
+ if (!allowedLoanTokens.includes(offer.loanToken.toLowerCase())) return { message: "Loan token is not allowed" };
4996
+ });
4997
+ /**
4998
+ * A validation rule that checks if the offer's collateral tokens are allowed for its chain.
4999
+ * @param collateralAssetsByChainId - Allowed collateral tokens indexed by chain id.
4789
5000
  * @returns The issue that was found. If the offer is valid, this will be undefined.
4790
5001
  */
4791
- const token = ({ assetsByChainId }) => single("token", "Validates that offer loan token and collateral tokens are in the allowed assets list for the offer chain", (offer) => {
4792
- const allowedAssets = assetsByChainId[offer.chainId]?.map((asset) => asset.toLowerCase());
4793
- if (!allowedAssets || allowedAssets.length === 0) return { message: `No allowed assets for chain ${offer.chainId}` };
4794
- if (!allowedAssets.includes(offer.loanToken.toLowerCase())) return { message: "Loan token is not allowed" };
4795
- if (offer.collaterals.some((collateral) => !allowedAssets.includes(collateral.asset.toLowerCase()))) return { message: "Collateral is not allowed" };
5002
+ const collateralToken = ({ collateralAssetsByChainId }) => single("collateral_token", "Validates that offer collateral tokens are in the allowed token list for the offer chain", (offer) => {
5003
+ const allowedCollateralTokens = collateralAssetsByChainId[offer.chainId]?.map((asset) => asset.toLowerCase()) ?? [];
5004
+ if (allowedCollateralTokens.length === 0) return { message: `No allowed collateral tokens for chain ${offer.chainId}` };
5005
+ if (offer.collaterals.length === 0) return { message: "At least one collateral token is required" };
5006
+ if (offer.collaterals.some((collateral) => !allowedCollateralTokens.includes(collateral.asset.toLowerCase()))) return { message: "Collateral token is not allowed" };
4796
5007
  });
4797
5008
  /**
4798
5009
  * A validation rule that checks if the offer's oracle addresses are allowed for its chain.
@@ -4835,9 +5046,11 @@ const amountMutualExclusivity = () => single("amount_mutual_exclusivity", "Valid
4835
5046
  //#region src/gatekeeper/morphoRules.ts
4836
5047
  const morphoRules = (chains$2) => {
4837
5048
  const assetsByChainId = {};
5049
+ const collateralAssetsByChainId = {};
4838
5050
  const oraclesByChainId = {};
4839
5051
  for (const chain of chains$2) {
4840
5052
  assetsByChainId[chain.id] = assets[chain.id.toString()] ?? [];
5053
+ collateralAssetsByChainId[chain.id] = collateralAssets[chain.id.toString()] ?? [];
4841
5054
  oraclesByChainId[chain.id] = oracles[chain.id.toString()] ?? [];
4842
5055
  }
4843
5056
  return [
@@ -4849,7 +5062,8 @@ const morphoRules = (chains$2) => {
4849
5062
  callbacks: [Type$1.BuyWithEmptyCallback, Type$1.SellWithEmptyCallback],
4850
5063
  allowedAddresses: []
4851
5064
  }),
4852
- token({ assetsByChainId }),
5065
+ loanToken({ assetsByChainId }),
5066
+ collateralToken({ collateralAssetsByChainId }),
4853
5067
  oracle({ oraclesByChainId })
4854
5068
  ];
4855
5069
  };
@@ -5175,5 +5389,5 @@ var utils_exports = /* @__PURE__ */ __exportAll({
5175
5389
  });
5176
5390
 
5177
5391
  //#endregion
5178
- export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainRegistry_exports as ChainRegistry, Collateral_exports as Collateral, ERC4626_exports as ERC4626, Errors_exports as Errors, Format_exports as Format, Gatekeeper_exports as Gatekeeper, Client_exports as GatekeeperClient, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Maturity_exports as Maturity, MempoolClient_exports as Mempool, Obligation_exports as Obligation, Offer_exports as Offer, Oracle_exports as Oracle, Position_exports as Position, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports$1 as RouterClient, Rules_exports as Rules, time_exports as Time, TradingFee_exports as TradingFee, Transfer_exports as Transfer, Tree_exports as Tree, utils_exports as Utils, Gate_exports as Validation, morphoRules };
5392
+ export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainRegistry_exports as ChainRegistry, Collateral_exports as Collateral, ERC4626_exports as ERC4626, Errors_exports as Errors, Format_exports as Format, Gatekeeper_exports as Gatekeeper, Client_exports as GatekeeperClient, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Maturity_exports as Maturity, MempoolClient_exports as Mempool, Obligation_exports as Obligation, Offer_exports as Offer, Oracle_exports as Oracle, Position_exports as Position, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports$1 as RouterClient, Rules_exports as Rules, Tick_exports as Tick, time_exports as Time, TradingFee_exports as TradingFee, Transfer_exports as Transfer, Tree_exports as Tree, utils_exports as Utils, Gate_exports as Validation, morphoRules };
5179
5393
  //# sourceMappingURL=index.browser.mjs.map