@morpho-org/blue-sdk 2.0.0-next.11 → 2.0.0-next.12

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.
package/lib/errors.d.ts CHANGED
@@ -35,6 +35,10 @@ export declare namespace BlueErrors {
35
35
  readonly marketId: MarketId;
36
36
  constructor(marketId: MarketId);
37
37
  }
38
+ class UnknownOraclePrice extends Error {
39
+ readonly marketId: MarketId;
40
+ constructor(marketId: MarketId);
41
+ }
38
42
  class InsufficientPosition extends Error {
39
43
  readonly user: Address;
40
44
  readonly marketId: MarketId;
package/lib/errors.js CHANGED
@@ -63,6 +63,14 @@ export var BlueErrors;
63
63
  }
64
64
  }
65
65
  BlueErrors.InsufficientLiquidity = InsufficientLiquidity;
66
+ class UnknownOraclePrice extends Error {
67
+ marketId;
68
+ constructor(marketId) {
69
+ super(`unknown oracle price of market "${marketId}"`);
70
+ this.marketId = marketId;
71
+ }
72
+ }
73
+ BlueErrors.UnknownOraclePrice = UnknownOraclePrice;
66
74
  class InsufficientPosition extends Error {
67
75
  user;
68
76
  marketId;
@@ -21,10 +21,10 @@ export interface MaxWithdrawCollateralOptions {
21
21
  export interface MaxPositionCapacities {
22
22
  supply: CapacityLimit;
23
23
  withdraw: CapacityLimit;
24
- borrow: CapacityLimit;
24
+ borrow: CapacityLimit | undefined;
25
25
  repay: CapacityLimit;
26
26
  supplyCollateral: CapacityLimit;
27
- withdrawCollateral: CapacityLimit;
27
+ withdrawCollateral: CapacityLimit | undefined;
28
28
  }
29
29
  export interface InputMarket {
30
30
  params: MarketParams;
@@ -34,7 +34,7 @@ export interface InputMarket {
34
34
  totalBorrowShares: bigint;
35
35
  lastUpdate: bigint;
36
36
  fee: bigint;
37
- price: bigint;
37
+ price?: bigint;
38
38
  rateAtTarget?: bigint;
39
39
  }
40
40
  /**
@@ -71,8 +71,9 @@ export declare class Market implements InputMarket {
71
71
  fee: bigint;
72
72
  /**
73
73
  * The price as returned by the market's oracle.
74
+ * `undefined` if the oracle is undefined or reverts.
74
75
  */
75
- price: bigint;
76
+ price?: bigint;
76
77
  /**
77
78
  * If the market uses the Adaptive Curve IRM, the rate at target utilization.
78
79
  * Undefined otherwise.
@@ -189,57 +190,65 @@ export declare class Market implements InputMarket {
189
190
  getRepayToUtilization(utilization: bigint): bigint;
190
191
  /**
191
192
  * Returns the value of a given amount of collateral quoted in loan assets.
193
+ * `undefined` iff the market's oracle is undefined or reverts.
192
194
  * @param collateral The amount of collateral to quote.
193
195
  */
194
- getCollateralValue(collateral: bigint): bigint;
196
+ getCollateralValue(collateral: bigint): bigint | undefined;
195
197
  /**
196
198
  * Returns the maximum debt allowed given a certain amount of collateral.
199
+ * `undefined` iff the market's oracle is undefined or reverts.
197
200
  * To calculate the amount of loan assets that can be borrowed, use `getMaxBorrowableAssets`.
198
201
  * @param collateral The amount of collateral to consider.
199
202
  */
200
- getMaxBorrowAssets(collateral: bigint, { maxLtv }?: MaxBorrowOptions): bigint;
203
+ getMaxBorrowAssets(collateral: bigint, { maxLtv }?: MaxBorrowOptions): bigint | undefined;
201
204
  /**
202
205
  * Returns the maximum amount of loan assets that can be borrowed given a certain borrow position.
206
+ * `undefined` iff the market's oracle is undefined or reverts.
203
207
  * @param position The borrow position to consider.
204
208
  */
205
209
  getMaxBorrowableAssets(position: {
206
210
  collateral: bigint;
207
211
  borrowShares: bigint;
208
- }): bigint;
212
+ }): bigint | undefined;
209
213
  /**
210
214
  * Returns the amount of collateral that would be seized in a liquidation given a certain amount of repaid shares.
215
+ * `undefined` iff the market's oracle is undefined or reverts.
211
216
  * @param repaidShares The amount of shares hypothetically repaid.
212
217
  */
213
- getLiquidationSeizedAssets(repaidShares: bigint): bigint;
218
+ getLiquidationSeizedAssets(repaidShares: bigint): bigint | undefined;
214
219
  /**
215
220
  * Returns the amount of borrow shares that would be repaid in a liquidation given a certain amount of seized collateral.
221
+ * `undefined` iff the market's oracle is undefined or reverts.
216
222
  * @param seizedAssets The amount of collateral hypothetically seized.
217
223
  */
218
- getLiquidationRepaidShares(seizedAssets: bigint): bigint;
224
+ getLiquidationRepaidShares(seizedAssets: bigint): bigint | undefined;
219
225
  /**
220
226
  * Returns the maximum amount of collateral that is worth being seized in a liquidation given a certain borrow position.
227
+ * `undefined` iff the market's oracle is undefined or reverts.
221
228
  * @param position The borrow position to consider.
222
229
  */
223
230
  getSeizableCollateral(position: {
224
231
  collateral: bigint;
225
232
  borrowShares: bigint;
226
- }): bigint;
233
+ }): bigint | undefined;
227
234
  /**
228
235
  * Returns the amount of collateral that can be withdrawn given a certain borrow position.
236
+ * `undefined` iff the market's oracle is undefined or reverts.
229
237
  * @param position The borrow position to consider.
230
238
  */
231
239
  getWithdrawableCollateral(position: {
232
240
  collateral: bigint;
233
241
  borrowShares: bigint;
234
- }, { maxLtv }?: MaxWithdrawCollateralOptions): bigint;
242
+ }, { maxLtv }?: MaxWithdrawCollateralOptions): bigint | undefined;
235
243
  /**
236
244
  * Returns whether a given borrow position is healthy.
245
+ * `undefined` iff the market's oracle is undefined or reverts.
237
246
  * @param position The borrow position to check.
238
247
  */
239
248
  isHealthy(position: {
240
249
  collateral: bigint;
241
250
  borrowShares: bigint;
242
- }): boolean;
251
+ }): boolean | undefined;
243
252
  /**
244
253
  * Returns the liquidation price of a given borrow position.
245
254
  * @param position The borrow position to consider.
@@ -251,13 +260,14 @@ export declare class Market implements InputMarket {
251
260
  /**
252
261
  * Returns the price variation required for the given position to reach its liquidation threshold (scaled by WAD).
253
262
  * Negative when healthy (the price needs to drop x%), positive when unhealthy (the price needs to soar x%).
263
+ * Returns `undefined` iff the market's price is undefined.
254
264
  * Returns null if the position is not a borrow.
255
265
  * @param position The borrow position to consider.
256
266
  */
257
267
  getPriceVariationToLiquidationPrice(position: {
258
268
  collateral: bigint;
259
269
  borrowShares: bigint;
260
- }): bigint | null;
270
+ }): bigint | null | undefined;
261
271
  /**
262
272
  * Returns the health factor of a given borrow position (scaled by WAD).
263
273
  * @param position The borrow position to consider.
@@ -265,7 +275,7 @@ export declare class Market implements InputMarket {
265
275
  getHealthFactor(position: {
266
276
  collateral: bigint;
267
277
  borrowShares: bigint;
268
- }): bigint | null;
278
+ }): bigint | null | undefined;
269
279
  /**
270
280
  * Returns the loan-to-value ratio of a given borrow position (scaled by WAD).
271
281
  * @param position The borrow position to consider.
@@ -273,7 +283,7 @@ export declare class Market implements InputMarket {
273
283
  getLtv(position: {
274
284
  collateral: bigint;
275
285
  borrowShares: bigint;
276
- }): bigint | null;
286
+ }): bigint | null | undefined;
277
287
  /**
278
288
  * Returns the usage ratio of the maximum borrow capacity given a certain borrow position (scaled by WAD).
279
289
  * @param position The borrow position to consider.
@@ -281,16 +291,17 @@ export declare class Market implements InputMarket {
281
291
  getBorrowCapacityUsage(position: {
282
292
  collateral: bigint;
283
293
  borrowShares: bigint;
284
- }): bigint | null;
294
+ }): bigint | undefined;
285
295
  /**
286
296
  * Returns the maximum amount of loan assets that can be borrowed given a certain borrow position
287
297
  * and the reason for the limit.
298
+ * Returns `undefined` iff the market's price is undefined.
288
299
  * @param position The borrow position to consider.
289
300
  */
290
301
  getBorrowCapacityLimit({ collateral, borrowShares, }: {
291
302
  collateral: bigint;
292
303
  borrowShares?: bigint;
293
- }, options?: MaxBorrowOptions): CapacityLimit;
304
+ }, options?: MaxBorrowOptions): CapacityLimit | undefined;
294
305
  /**
295
306
  * Returns the maximum amount of loan assets that can be repaid given a certain borrow position
296
307
  * and a balance of loan assets, and the reason for the limit.
@@ -308,12 +319,13 @@ export declare class Market implements InputMarket {
308
319
  /**
309
320
  * Returns the maximum amount of collateral assets that can be withdrawn given a certain borrow position
310
321
  * and the reason for the limit.
322
+ * Returns `undefined` iff the market's price is undefined.
311
323
  * @param position The borrow position to consider.
312
324
  */
313
325
  getWithdrawCollateralCapacityLimit(position: {
314
326
  collateral: bigint;
315
327
  borrowShares: bigint;
316
- }, options?: MaxWithdrawCollateralOptions): CapacityLimit;
328
+ }, options?: MaxWithdrawCollateralOptions): CapacityLimit | undefined;
317
329
  /**
318
330
  * Returns the maximum capacity for all interactions with Morpho Blue given a certain position
319
331
  * and loan and collateral balances.
@@ -44,6 +44,7 @@ export class Market {
44
44
  fee;
45
45
  /**
46
46
  * The price as returned by the market's oracle.
47
+ * `undefined` if the oracle is undefined or reverts.
47
48
  */
48
49
  price;
49
50
  /**
@@ -266,6 +267,7 @@ export class Market {
266
267
  }
267
268
  /**
268
269
  * Returns the value of a given amount of collateral quoted in loan assets.
270
+ * `undefined` iff the market's oracle is undefined or reverts.
269
271
  * @param collateral The amount of collateral to quote.
270
272
  */
271
273
  getCollateralValue(collateral) {
@@ -273,6 +275,7 @@ export class Market {
273
275
  }
274
276
  /**
275
277
  * Returns the maximum debt allowed given a certain amount of collateral.
278
+ * `undefined` iff the market's oracle is undefined or reverts.
276
279
  * To calculate the amount of loan assets that can be borrowed, use `getMaxBorrowableAssets`.
277
280
  * @param collateral The amount of collateral to consider.
278
281
  */
@@ -283,6 +286,7 @@ export class Market {
283
286
  }
284
287
  /**
285
288
  * Returns the maximum amount of loan assets that can be borrowed given a certain borrow position.
289
+ * `undefined` iff the market's oracle is undefined or reverts.
286
290
  * @param position The borrow position to consider.
287
291
  */
288
292
  getMaxBorrowableAssets(position) {
@@ -290,6 +294,7 @@ export class Market {
290
294
  }
291
295
  /**
292
296
  * Returns the amount of collateral that would be seized in a liquidation given a certain amount of repaid shares.
297
+ * `undefined` iff the market's oracle is undefined or reverts.
293
298
  * @param repaidShares The amount of shares hypothetically repaid.
294
299
  */
295
300
  getLiquidationSeizedAssets(repaidShares) {
@@ -297,6 +302,7 @@ export class Market {
297
302
  }
298
303
  /**
299
304
  * Returns the amount of borrow shares that would be repaid in a liquidation given a certain amount of seized collateral.
305
+ * `undefined` iff the market's oracle is undefined or reverts.
300
306
  * @param seizedAssets The amount of collateral hypothetically seized.
301
307
  */
302
308
  getLiquidationRepaidShares(seizedAssets) {
@@ -304,6 +310,7 @@ export class Market {
304
310
  }
305
311
  /**
306
312
  * Returns the maximum amount of collateral that is worth being seized in a liquidation given a certain borrow position.
313
+ * `undefined` iff the market's oracle is undefined or reverts.
307
314
  * @param position The borrow position to consider.
308
315
  */
309
316
  getSeizableCollateral(position) {
@@ -311,6 +318,7 @@ export class Market {
311
318
  }
312
319
  /**
313
320
  * Returns the amount of collateral that can be withdrawn given a certain borrow position.
321
+ * `undefined` iff the market's oracle is undefined or reverts.
314
322
  * @param position The borrow position to consider.
315
323
  */
316
324
  getWithdrawableCollateral(position, { maxLtv = this.params.lltv } = {}) {
@@ -320,6 +328,7 @@ export class Market {
320
328
  }
321
329
  /**
322
330
  * Returns whether a given borrow position is healthy.
331
+ * `undefined` iff the market's oracle is undefined or reverts.
323
332
  * @param position The borrow position to check.
324
333
  */
325
334
  isHealthy(position) {
@@ -335,6 +344,7 @@ export class Market {
335
344
  /**
336
345
  * Returns the price variation required for the given position to reach its liquidation threshold (scaled by WAD).
337
346
  * Negative when healthy (the price needs to drop x%), positive when unhealthy (the price needs to soar x%).
347
+ * Returns `undefined` iff the market's price is undefined.
338
348
  * Returns null if the position is not a borrow.
339
349
  * @param position The borrow position to consider.
340
350
  */
@@ -365,11 +375,15 @@ export class Market {
365
375
  /**
366
376
  * Returns the maximum amount of loan assets that can be borrowed given a certain borrow position
367
377
  * and the reason for the limit.
378
+ * Returns `undefined` iff the market's price is undefined.
368
379
  * @param position The borrow position to consider.
369
380
  */
370
381
  getBorrowCapacityLimit({ collateral, borrowShares = 0n, }, options) {
382
+ const maxBorrowAssets = this.getMaxBorrowAssets(collateral, options);
383
+ if (maxBorrowAssets == null)
384
+ return;
371
385
  // handle edge cases when the user is liquidatable (maxBorrow < borrow)
372
- const maxBorrowableAssets = MathLib.zeroFloorSub(this.getMaxBorrowAssets(collateral, options), this.toBorrowAssets(borrowShares));
386
+ const maxBorrowableAssets = MathLib.zeroFloorSub(maxBorrowAssets, this.toBorrowAssets(borrowShares));
373
387
  const { liquidity } = this;
374
388
  if (maxBorrowableAssets > liquidity)
375
389
  return {
@@ -419,10 +433,13 @@ export class Market {
419
433
  /**
420
434
  * Returns the maximum amount of collateral assets that can be withdrawn given a certain borrow position
421
435
  * and the reason for the limit.
436
+ * Returns `undefined` iff the market's price is undefined.
422
437
  * @param position The borrow position to consider.
423
438
  */
424
439
  getWithdrawCollateralCapacityLimit(position, options) {
425
440
  const withdrawableCollateral = this.getWithdrawableCollateral(position, options);
441
+ if (withdrawableCollateral == null)
442
+ return;
426
443
  if (position.collateral > withdrawableCollateral)
427
444
  return {
428
445
  value: withdrawableCollateral,
@@ -95,68 +95,102 @@ export declare namespace MarketUtils {
95
95
  function getCollateralPower(collateral: BigIntish, { lltv }: {
96
96
  lltv: BigIntish;
97
97
  }): bigint;
98
+ /**
99
+ * Returns the value of a given amount of collateral quoted in loan assets.
100
+ * Return `undefined` iff the market's price is undefined.
101
+ */
98
102
  function getCollateralValue(collateral: BigIntish, { price }: {
99
- price: BigIntish;
100
- }): bigint;
103
+ price?: BigIntish;
104
+ }): bigint | undefined;
105
+ /**
106
+ * Returns the maximum debt allowed given a certain amount of collateral.
107
+ * Return `undefined` iff the market's price is undefined.
108
+ * To calculate the amount of loan assets that can be borrowed, use `getMaxBorrowableAssets`.
109
+ */
101
110
  function getMaxBorrowAssets(collateral: BigIntish, market: {
102
- price: BigIntish;
111
+ price?: BigIntish;
103
112
  }, { lltv }: {
104
113
  lltv: BigIntish;
105
- }): bigint;
114
+ }): bigint | undefined;
115
+ /**
116
+ * Returns the maximum amount of loan assets that can be borrowed given a certain borrow position.
117
+ * Return `undefined` iff the market's price is undefined.
118
+ */
106
119
  function getMaxBorrowableAssets({ collateral, borrowShares, }: {
107
120
  collateral: BigIntish;
108
121
  borrowShares: BigIntish;
109
122
  }, market: {
110
123
  totalBorrowAssets: BigIntish;
111
124
  totalBorrowShares: BigIntish;
112
- price: BigIntish;
125
+ price?: BigIntish;
113
126
  }, marketParams: {
114
127
  lltv: BigIntish;
115
- }): bigint;
128
+ }): bigint | undefined;
129
+ /**
130
+ * Returns the amount of collateral that would be seized in a liquidation given a certain amount of repaid shares.
131
+ * Return `undefined` iff the market's price is undefined.
132
+ */
116
133
  function getLiquidationSeizedAssets(repaidShares: BigIntish, market: {
117
134
  totalBorrowAssets: BigIntish;
118
135
  totalBorrowShares: BigIntish;
119
- price: BigIntish;
136
+ price?: BigIntish;
120
137
  }, config: {
121
138
  lltv: BigIntish;
122
- }): bigint;
139
+ }): bigint | undefined;
140
+ /**
141
+ * Returns the amount of borrow shares that would be repaid in a liquidation given a certain amount of seized collateral.
142
+ * Return `undefined` iff the market's price is undefined.
143
+ */
123
144
  function getLiquidationRepaidShares(seizedAssets: BigIntish, market: {
124
145
  totalBorrowAssets: BigIntish;
125
146
  totalBorrowShares: BigIntish;
126
- price: BigIntish;
147
+ price?: BigIntish;
127
148
  }, config: {
128
149
  lltv: BigIntish;
129
- }): bigint;
150
+ }): bigint | undefined;
151
+ /**
152
+ * Returns the maximum amount of collateral that is worth being seized in a liquidation given a certain borrow position.
153
+ * Return `undefined` iff the market's price is undefined.
154
+ */
130
155
  function getSeizableCollateral(position: {
131
156
  collateral: BigIntish;
132
157
  borrowShares: BigIntish;
133
158
  }, market: {
134
159
  totalBorrowAssets: BigIntish;
135
160
  totalBorrowShares: BigIntish;
136
- price: BigIntish;
161
+ price?: BigIntish;
137
162
  }, config: {
138
163
  lltv: BigIntish;
139
- }): bigint;
164
+ }): bigint | undefined;
165
+ /**
166
+ * Returns the amount of collateral that can be withdrawn given a certain borrow position.
167
+ * Return `undefined` iff the market's price is undefined.
168
+ */
140
169
  function getWithdrawableCollateral({ collateral, borrowShares, }: {
141
170
  collateral: BigIntish;
142
171
  borrowShares: BigIntish;
143
172
  }, market: {
144
173
  totalBorrowAssets: BigIntish;
145
174
  totalBorrowShares: BigIntish;
146
- price: BigIntish;
175
+ price?: BigIntish;
147
176
  }, { lltv }: {
148
177
  lltv: BigIntish;
149
- }): bigint;
178
+ }): bigint | undefined;
179
+ /**
180
+ * Returns whether a given borrow position is healthy.
181
+ * Return `undefined` iff the market's price is undefined.
182
+ * @param position The borrow position to check.
183
+ */
150
184
  function isHealthy({ collateral, borrowShares, }: {
151
185
  collateral: BigIntish;
152
186
  borrowShares: BigIntish;
153
187
  }, market: {
154
188
  totalBorrowAssets: BigIntish;
155
189
  totalBorrowShares: BigIntish;
156
- price: BigIntish;
190
+ price?: BigIntish;
157
191
  }, marketParams: {
158
192
  lltv: BigIntish;
159
- }): boolean;
193
+ }): boolean | undefined;
160
194
  /**
161
195
  * Returns the price of the collateral quoted in the loan token (e.g. ETH/DAI)
162
196
  * that set the user's position to be liquidatable.
@@ -174,6 +208,7 @@ export declare namespace MarketUtils {
174
208
  /**
175
209
  * Returns the price variation required for the given position to reach its liquidation threshold (scaled by WAD).
176
210
  * Negative when healthy (the price needs to drop x%), positive when unhealthy (the price needs to soar x%).
211
+ * Returns `undefined` iff the market's price is undefined.
177
212
  * Returns null if the position is not a borrow.
178
213
  */
179
214
  function getPriceVariationToLiquidationPrice(position: {
@@ -182,38 +217,52 @@ export declare namespace MarketUtils {
182
217
  }, market: {
183
218
  totalBorrowAssets: BigIntish;
184
219
  totalBorrowShares: BigIntish;
185
- price: BigIntish;
220
+ price?: BigIntish;
186
221
  }, marketParams: {
187
222
  lltv: BigIntish;
188
- }): bigint | null;
223
+ }): bigint | null | undefined;
224
+ /**
225
+ * Returns the health factor of a given borrow position (scaled by WAD).
226
+ * Returns `undefined` iff the market's price is undefined.
227
+ * Returns null if the position is not a borrow.
228
+ */
189
229
  function getHealthFactor({ collateral, borrowShares, }: {
190
230
  collateral: BigIntish;
191
231
  borrowShares: BigIntish;
192
232
  }, market: {
193
233
  totalBorrowAssets: BigIntish;
194
234
  totalBorrowShares: BigIntish;
195
- price: BigIntish;
235
+ price?: BigIntish;
196
236
  }, marketParams: {
197
237
  lltv: BigIntish;
198
- }): bigint | null;
238
+ }): bigint | null | undefined;
239
+ /**
240
+ * Returns the loan-to-value ratio of a given borrow position (scaled by WAD).
241
+ * Returns `undefined` iff the market's price is undefined.
242
+ * Returns null if the position is not a borrow.
243
+ */
199
244
  function getLtv({ collateral, borrowShares, }: {
200
245
  collateral: BigIntish;
201
246
  borrowShares: BigIntish;
202
247
  }, market: {
203
248
  totalBorrowAssets: BigIntish;
204
249
  totalBorrowShares: BigIntish;
205
- price: BigIntish;
206
- }): bigint | null;
250
+ price?: BigIntish;
251
+ }): bigint | null | undefined;
252
+ /**
253
+ * Returns the usage ratio of the maximum borrow capacity given a certain borrow position (scaled by WAD).
254
+ * Returns `undefined` iff the market's price is undefined.
255
+ */
207
256
  function getBorrowCapacityUsage(position: {
208
257
  collateral: BigIntish;
209
258
  borrowShares: BigIntish;
210
259
  }, market: {
211
260
  totalBorrowAssets: BigIntish;
212
261
  totalBorrowShares: BigIntish;
213
- price: BigIntish;
262
+ price?: BigIntish;
214
263
  }, marketParams: {
215
264
  lltv: BigIntish;
216
- }): bigint | null;
265
+ }): bigint | undefined;
217
266
  function toSupplyAssets(shares: BigIntish, market: {
218
267
  totalSupplyAssets: BigIntish;
219
268
  totalSupplyShares: BigIntish;
@@ -132,46 +132,98 @@ export var MarketUtils;
132
132
  return MathLib.wMulDown(collateral, lltv);
133
133
  }
134
134
  MarketUtils.getCollateralPower = getCollateralPower;
135
+ /**
136
+ * Returns the value of a given amount of collateral quoted in loan assets.
137
+ * Return `undefined` iff the market's price is undefined.
138
+ */
135
139
  function getCollateralValue(collateral, { price }) {
140
+ if (price == null)
141
+ return;
136
142
  return MathLib.mulDivDown(collateral, price, ORACLE_PRICE_SCALE);
137
143
  }
138
144
  MarketUtils.getCollateralValue = getCollateralValue;
145
+ /**
146
+ * Returns the maximum debt allowed given a certain amount of collateral.
147
+ * Return `undefined` iff the market's price is undefined.
148
+ * To calculate the amount of loan assets that can be borrowed, use `getMaxBorrowableAssets`.
149
+ */
139
150
  function getMaxBorrowAssets(collateral, market, { lltv }) {
140
- return MathLib.wMulDown(getCollateralValue(collateral, market), lltv);
151
+ const collateralValue = getCollateralValue(collateral, market);
152
+ if (collateralValue == null)
153
+ return;
154
+ return MathLib.wMulDown(collateralValue, lltv);
141
155
  }
142
156
  MarketUtils.getMaxBorrowAssets = getMaxBorrowAssets;
157
+ /**
158
+ * Returns the maximum amount of loan assets that can be borrowed given a certain borrow position.
159
+ * Return `undefined` iff the market's price is undefined.
160
+ */
143
161
  function getMaxBorrowableAssets({ collateral, borrowShares, }, market, marketParams) {
144
- return MathLib.zeroFloorSub(getMaxBorrowAssets(collateral, market, marketParams), toBorrowAssets(borrowShares, market));
162
+ const maxBorrowAssets = getMaxBorrowAssets(collateral, market, marketParams);
163
+ if (maxBorrowAssets == null)
164
+ return;
165
+ return MathLib.zeroFloorSub(maxBorrowAssets, toBorrowAssets(borrowShares, market));
145
166
  }
146
167
  MarketUtils.getMaxBorrowableAssets = getMaxBorrowableAssets;
168
+ /**
169
+ * Returns the amount of collateral that would be seized in a liquidation given a certain amount of repaid shares.
170
+ * Return `undefined` iff the market's price is undefined.
171
+ */
147
172
  function getLiquidationSeizedAssets(repaidShares, market, config) {
173
+ if (market.price == null)
174
+ return;
148
175
  market.price = BigInt(market.price);
149
176
  if (market.price === 0n)
150
177
  return 0n;
151
178
  return MathLib.mulDivDown(MathLib.wMulDown(toBorrowAssets(repaidShares, market, "Down"), getLiquidationIncentiveFactor(config)), ORACLE_PRICE_SCALE, market.price);
152
179
  }
153
180
  MarketUtils.getLiquidationSeizedAssets = getLiquidationSeizedAssets;
181
+ /**
182
+ * Returns the amount of borrow shares that would be repaid in a liquidation given a certain amount of seized collateral.
183
+ * Return `undefined` iff the market's price is undefined.
184
+ */
154
185
  function getLiquidationRepaidShares(seizedAssets, market, config) {
186
+ if (market.price == null)
187
+ return;
155
188
  return toBorrowShares(MathLib.wDivUp(MathLib.mulDivUp(seizedAssets, market.price, ORACLE_PRICE_SCALE), getLiquidationIncentiveFactor(config)), market, "Up");
156
189
  }
157
190
  MarketUtils.getLiquidationRepaidShares = getLiquidationRepaidShares;
191
+ /**
192
+ * Returns the maximum amount of collateral that is worth being seized in a liquidation given a certain borrow position.
193
+ * Return `undefined` iff the market's price is undefined.
194
+ */
158
195
  function getSeizableCollateral(position, market, config) {
196
+ if (market.price == null)
197
+ return; // Must be checked before calling `isHealthy`.
159
198
  market.price = BigInt(market.price);
160
199
  if (market.price === 0n || isHealthy(position, market, config))
161
200
  return 0n;
162
201
  return MathLib.min(position.collateral, getLiquidationSeizedAssets(position.borrowShares, market, config));
163
202
  }
164
203
  MarketUtils.getSeizableCollateral = getSeizableCollateral;
204
+ /**
205
+ * Returns the amount of collateral that can be withdrawn given a certain borrow position.
206
+ * Return `undefined` iff the market's price is undefined.
207
+ */
165
208
  function getWithdrawableCollateral({ collateral, borrowShares, }, market, { lltv }) {
209
+ if (market.price == null)
210
+ return;
166
211
  market.price = BigInt(market.price);
167
212
  if (market.price === 0n)
168
213
  return 0n;
169
214
  return MathLib.zeroFloorSub(collateral, MathLib.wDivUp(MathLib.mulDivUp(toBorrowAssets(borrowShares, market), ORACLE_PRICE_SCALE, market.price), lltv));
170
215
  }
171
216
  MarketUtils.getWithdrawableCollateral = getWithdrawableCollateral;
217
+ /**
218
+ * Returns whether a given borrow position is healthy.
219
+ * Return `undefined` iff the market's price is undefined.
220
+ * @param position The borrow position to check.
221
+ */
172
222
  function isHealthy({ collateral, borrowShares, }, market, marketParams) {
173
- return (getMaxBorrowAssets(collateral, market, marketParams) >=
174
- toBorrowAssets(borrowShares, market));
223
+ const maxBorrowAssets = getMaxBorrowAssets(collateral, market, marketParams);
224
+ if (maxBorrowAssets == null)
225
+ return;
226
+ return maxBorrowAssets >= toBorrowAssets(borrowShares, market);
175
227
  }
176
228
  MarketUtils.isHealthy = isHealthy;
177
229
  /**
@@ -194,9 +246,12 @@ export var MarketUtils;
194
246
  /**
195
247
  * Returns the price variation required for the given position to reach its liquidation threshold (scaled by WAD).
196
248
  * Negative when healthy (the price needs to drop x%), positive when unhealthy (the price needs to soar x%).
249
+ * Returns `undefined` iff the market's price is undefined.
197
250
  * Returns null if the position is not a borrow.
198
251
  */
199
252
  function getPriceVariationToLiquidationPrice(position, market, marketParams) {
253
+ if (market.price == null)
254
+ return;
200
255
  market.price = BigInt(market.price);
201
256
  if (market.price === 0n)
202
257
  return null;
@@ -206,6 +261,11 @@ export var MarketUtils;
206
261
  return MathLib.wDivUp(liquidationPrice, market.price) - MathLib.WAD;
207
262
  }
208
263
  MarketUtils.getPriceVariationToLiquidationPrice = getPriceVariationToLiquidationPrice;
264
+ /**
265
+ * Returns the health factor of a given borrow position (scaled by WAD).
266
+ * Returns `undefined` iff the market's price is undefined.
267
+ * Returns null if the position is not a borrow.
268
+ */
209
269
  function getHealthFactor({ collateral, borrowShares, }, market, marketParams) {
210
270
  borrowShares = BigInt(borrowShares);
211
271
  market.totalBorrowShares = BigInt(market.totalBorrowShares);
@@ -215,24 +275,39 @@ export var MarketUtils;
215
275
  if (borrowAssets === 0n)
216
276
  return MathLib.MAX_UINT_256;
217
277
  const maxBorrowAssets = getMaxBorrowAssets(collateral, market, marketParams);
278
+ if (maxBorrowAssets == null)
279
+ return;
218
280
  return MathLib.wDivDown(maxBorrowAssets, borrowAssets);
219
281
  }
220
282
  MarketUtils.getHealthFactor = getHealthFactor;
283
+ /**
284
+ * Returns the loan-to-value ratio of a given borrow position (scaled by WAD).
285
+ * Returns `undefined` iff the market's price is undefined.
286
+ * Returns null if the position is not a borrow.
287
+ */
221
288
  function getLtv({ collateral, borrowShares, }, market) {
222
289
  borrowShares = BigInt(borrowShares);
223
290
  market.totalBorrowShares = BigInt(market.totalBorrowShares);
224
291
  if (borrowShares === 0n || market.totalBorrowShares === 0n)
225
292
  return null;
226
293
  const collateralValue = getCollateralValue(collateral, market);
294
+ if (collateralValue == null)
295
+ return;
227
296
  if (collateralValue === 0n)
228
297
  return MathLib.MAX_UINT_256;
229
298
  return MathLib.wDivUp(toBorrowAssets(borrowShares, market), collateralValue);
230
299
  }
231
300
  MarketUtils.getLtv = getLtv;
301
+ /**
302
+ * Returns the usage ratio of the maximum borrow capacity given a certain borrow position (scaled by WAD).
303
+ * Returns `undefined` iff the market's price is undefined.
304
+ */
232
305
  function getBorrowCapacityUsage(position, market, marketParams) {
233
306
  const hf = getHealthFactor(position, market, marketParams);
307
+ if (hf === undefined)
308
+ return;
234
309
  if (hf === null)
235
- return null;
310
+ return 0n;
236
311
  if (hf === 0n)
237
312
  return MathLib.MAX_UINT_256;
238
313
  return MathLib.wDivUp(MathLib.WAD, hf);
@@ -42,28 +42,34 @@ export declare class AccrualPosition extends Position implements InputAccrualPos
42
42
  get borrowAssets(): bigint;
43
43
  /**
44
44
  * The value of this position's collateral quoted in loan assets.
45
+ * `undefined` iff the market's oracle is undefined or reverts.
45
46
  */
46
- get collateralValue(): bigint;
47
+ get collateralValue(): bigint | undefined;
47
48
  /**
48
49
  * The maximum amount of loan assets that can be borrowed against this position's collateral.
50
+ * `undefined` iff the market's oracle is undefined or reverts.
49
51
  */
50
- get maxBorrowAssets(): bigint;
52
+ get maxBorrowAssets(): bigint | undefined;
51
53
  /**
52
54
  * The maximum additional amount of assets that can be borrowed against this position's collateral.
55
+ * `undefined` iff the market's oracle is undefined or reverts.
53
56
  */
54
- get maxBorrowableAssets(): bigint;
57
+ get maxBorrowableAssets(): bigint | undefined;
55
58
  /**
56
59
  * The maximum amount of collateral that can be seized in exchange for the outstanding debt.
60
+ * `undefined` iff the market's oracle is undefined or reverts.
57
61
  */
58
- get seizableCollateral(): bigint;
62
+ get seizableCollateral(): bigint | undefined;
59
63
  /**
60
64
  * The maximum amount of collateral that can be withdrawn.
65
+ * `undefined` iff the market's oracle is undefined or reverts.
61
66
  */
62
- get withdrawableCollateral(): bigint;
67
+ get withdrawableCollateral(): bigint | undefined;
63
68
  /**
64
69
  * Whether this position is healthy.
70
+ * `undefined` iff the market's oracle is undefined or reverts.
65
71
  */
66
- get isHealthy(): boolean;
72
+ get isHealthy(): boolean | undefined;
67
73
  /**
68
74
  * The price of the collateral quoted in loan assets that would allow this position to be liquidated.
69
75
  */
@@ -71,27 +77,30 @@ export declare class AccrualPosition extends Position implements InputAccrualPos
71
77
  /**
72
78
  * The price variation required for the position to reach its liquidation threshold (scaled by WAD).
73
79
  * Negative when healthy (the price needs to drop x%), positive when unhealthy (the price needs to soar x%).
74
- * Returns null if the position is not a borrow.
80
+ * `undefined` iff the market's oracle is undefined or reverts.
81
+ * Null if the position is not a borrow.
75
82
  */
76
- get priceVariationToLiquidationPrice(): bigint | null;
83
+ get priceVariationToLiquidationPrice(): bigint | null | undefined;
77
84
  /**
78
85
  * This position's Loan-To-Value (debt over collateral power, scaled by WAD).
79
86
  * If the collateral price is 0, LTV is `MaxUint256`.
87
+ * `undefined` iff the market's oracle is undefined or reverts.
80
88
  */
81
- get ltv(): bigint | null;
89
+ get ltv(): bigint | null | undefined;
82
90
  /**
83
91
  * This position's health factor (collateral power over debt, scaled by WAD).
84
92
  * If the debt is 0, health factor is `MaxUint256`.
93
+ * `undefined` iff the market's oracle is undefined or reverts.
85
94
  */
86
- get healthFactor(): bigint | null;
95
+ get healthFactor(): bigint | null | undefined;
87
96
  /**
88
97
  * The percentage of this position's borrow power currently used (scaled by WAD).
89
98
  * If the collateral price is 0, usage is `MaxUint256`.
90
99
  */
91
- get borrowCapacityUsage(): bigint | null;
92
- get borrowCapacityLimit(): import("../market/Market.js").CapacityLimit;
100
+ get borrowCapacityUsage(): bigint | undefined;
101
+ get borrowCapacityLimit(): import("../market/Market.js").CapacityLimit | undefined;
93
102
  get withdrawCapacityLimit(): import("../market/Market.js").CapacityLimit;
94
- get withdrawCollateralCapacityLimit(): import("../market/Market.js").CapacityLimit;
103
+ get withdrawCollateralCapacityLimit(): import("../market/Market.js").CapacityLimit | undefined;
95
104
  /**
96
105
  * Returns a new position derived from this position, whose interest has been accrued up to the given timestamp.
97
106
  * @param timestamp The timestamp at which to accrue interest. Must be greater than or equal to the market's `lastUpdate`.
@@ -46,36 +46,42 @@ export class AccrualPosition extends Position {
46
46
  }
47
47
  /**
48
48
  * The value of this position's collateral quoted in loan assets.
49
+ * `undefined` iff the market's oracle is undefined or reverts.
49
50
  */
50
51
  get collateralValue() {
51
52
  return this.market.getCollateralValue(this.collateral);
52
53
  }
53
54
  /**
54
55
  * The maximum amount of loan assets that can be borrowed against this position's collateral.
56
+ * `undefined` iff the market's oracle is undefined or reverts.
55
57
  */
56
58
  get maxBorrowAssets() {
57
59
  return this.market.getMaxBorrowAssets(this.collateral);
58
60
  }
59
61
  /**
60
62
  * The maximum additional amount of assets that can be borrowed against this position's collateral.
63
+ * `undefined` iff the market's oracle is undefined or reverts.
61
64
  */
62
65
  get maxBorrowableAssets() {
63
66
  return this.market.getMaxBorrowableAssets(this);
64
67
  }
65
68
  /**
66
69
  * The maximum amount of collateral that can be seized in exchange for the outstanding debt.
70
+ * `undefined` iff the market's oracle is undefined or reverts.
67
71
  */
68
72
  get seizableCollateral() {
69
73
  return this.market.getSeizableCollateral(this);
70
74
  }
71
75
  /**
72
76
  * The maximum amount of collateral that can be withdrawn.
77
+ * `undefined` iff the market's oracle is undefined or reverts.
73
78
  */
74
79
  get withdrawableCollateral() {
75
80
  return this.market.getWithdrawableCollateral(this);
76
81
  }
77
82
  /**
78
83
  * Whether this position is healthy.
84
+ * `undefined` iff the market's oracle is undefined or reverts.
79
85
  */
80
86
  get isHealthy() {
81
87
  return this.market.isHealthy(this);
@@ -89,7 +95,8 @@ export class AccrualPosition extends Position {
89
95
  /**
90
96
  * The price variation required for the position to reach its liquidation threshold (scaled by WAD).
91
97
  * Negative when healthy (the price needs to drop x%), positive when unhealthy (the price needs to soar x%).
92
- * Returns null if the position is not a borrow.
98
+ * `undefined` iff the market's oracle is undefined or reverts.
99
+ * Null if the position is not a borrow.
93
100
  */
94
101
  get priceVariationToLiquidationPrice() {
95
102
  return this.market.getPriceVariationToLiquidationPrice(this);
@@ -97,6 +104,7 @@ export class AccrualPosition extends Position {
97
104
  /**
98
105
  * This position's Loan-To-Value (debt over collateral power, scaled by WAD).
99
106
  * If the collateral price is 0, LTV is `MaxUint256`.
107
+ * `undefined` iff the market's oracle is undefined or reverts.
100
108
  */
101
109
  get ltv() {
102
110
  return this.market.getLtv(this);
@@ -104,6 +112,7 @@ export class AccrualPosition extends Position {
104
112
  /**
105
113
  * This position's health factor (collateral power over debt, scaled by WAD).
106
114
  * If the debt is 0, health factor is `MaxUint256`.
115
+ * `undefined` iff the market's oracle is undefined or reverts.
107
116
  */
108
117
  get healthFactor() {
109
118
  return this.market.getHealthFactor(this);
@@ -134,61 +143,53 @@ export class AccrualPosition extends Position {
134
143
  supply(assets, shares, timestamp) {
135
144
  let { market } = this;
136
145
  ({ market, assets, shares } = market.supply(assets, shares, timestamp));
137
- this.supplyShares += shares;
138
- return {
139
- position: new AccrualPosition(this, market),
140
- assets,
141
- shares,
142
- };
146
+ const position = new AccrualPosition(this, market);
147
+ position.supplyShares += shares;
148
+ return { position, assets, shares };
143
149
  }
144
150
  withdraw(assets, shares, timestamp) {
145
151
  let { market } = this;
146
152
  ({ market, assets, shares } = market.withdraw(assets, shares, timestamp));
147
- this.supplyShares -= shares;
148
- if (this.supplyShares < 0n)
149
- throw new BlueErrors.InsufficientPosition(this.user, this.marketId);
150
- return {
151
- position: new AccrualPosition(this, market),
152
- assets,
153
- shares,
154
- };
153
+ const position = new AccrualPosition(this, market);
154
+ position.supplyShares -= shares;
155
+ if (position.supplyShares < 0n)
156
+ throw new BlueErrors.InsufficientPosition(position.user, position.marketId);
157
+ return { position, assets, shares };
155
158
  }
156
159
  supplyCollateral(assets) {
157
160
  this.collateral += assets;
158
161
  return new AccrualPosition(this, new Market(this.market));
159
162
  }
160
163
  withdrawCollateral(assets, timestamp) {
161
- const market = this.market.accrueInterest(timestamp);
162
- this.collateral -= assets;
163
- if (this.collateral < 0n)
164
- throw new BlueErrors.InsufficientPosition(this.user, this.marketId);
165
- if (!market.isHealthy(this))
166
- throw new BlueErrors.InsufficientCollateral(this.user, this.marketId);
167
- return new AccrualPosition(this, market);
164
+ if (this.market.price == null)
165
+ throw new BlueErrors.UnknownOraclePrice(this.marketId);
166
+ const position = this.accrueInterest(timestamp);
167
+ position.collateral -= assets;
168
+ if (position.collateral < 0n)
169
+ throw new BlueErrors.InsufficientPosition(position.user, position.marketId);
170
+ if (!position.isHealthy)
171
+ throw new BlueErrors.InsufficientCollateral(position.user, position.marketId);
172
+ return position;
168
173
  }
169
174
  borrow(assets, shares, timestamp) {
170
175
  let { market } = this;
176
+ if (market.price == null)
177
+ throw new BlueErrors.UnknownOraclePrice(market.id);
171
178
  ({ market, assets, shares } = market.borrow(assets, shares, timestamp));
172
- this.borrowShares += shares;
173
- if (!market.isHealthy(this))
179
+ const position = new AccrualPosition(this, market);
180
+ position.borrowShares += shares;
181
+ if (!position.isHealthy)
174
182
  throw new BlueErrors.InsufficientCollateral(this.user, this.marketId);
175
- return {
176
- position: new AccrualPosition(this, market),
177
- assets,
178
- shares,
179
- };
183
+ return { position, assets, shares };
180
184
  }
181
185
  repay(assets, shares, timestamp) {
182
186
  let { market } = this;
183
187
  ({ market, assets, shares } = market.repay(assets, shares, timestamp));
184
- this.borrowShares -= shares;
185
- if (this.borrowShares < 0n)
186
- throw new BlueErrors.InsufficientPosition(this.user, this.marketId);
187
- return {
188
- position: new AccrualPosition(this, market),
189
- assets,
190
- shares,
191
- };
188
+ const position = new AccrualPosition(this, market);
189
+ position.borrowShares -= shares;
190
+ if (position.borrowShares < 0n)
191
+ throw new BlueErrors.InsufficientPosition(position.user, position.marketId);
192
+ return { position, assets, shares };
192
193
  }
193
194
  getRepayCapacityLimit(loanTokenBalance) {
194
195
  return this.market.getRepayCapacityLimit(this.borrowShares, loanTokenBalance);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@morpho-org/blue-sdk",
3
3
  "description": "Framework-agnostic package that defines Morpho-related entity classes (such as `Market`, `Token`, `Vault`).",
4
- "version": "2.0.0-next.11",
4
+ "version": "2.0.0-next.12",
5
5
  "author": "Morpho Association <contact@morpho.org>",
6
6
  "contributors": [
7
7
  "Rubilmax <rmilon@gmail.com>"