@morpho-org/midnight-sdk 2.1.0-next.0 → 2.1.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.
- package/lib/cjs/api/version.generated.d.ts +1 -1
- package/lib/cjs/api/version.generated.js +1 -1
- package/lib/cjs/errors.d.ts +27 -13
- package/lib/cjs/errors.js +39 -8
- package/lib/cjs/offers/Offer.d.ts +50 -0
- package/lib/cjs/offers/Offer.js +53 -0
- package/lib/cjs/offers/OfferUtils.d.ts +108 -0
- package/lib/cjs/offers/OfferUtils.js +116 -0
- package/lib/cjs/position/PositionUtils.js +35 -11
- package/lib/esm/api/version.generated.d.ts +1 -1
- package/lib/esm/api/version.generated.js +1 -1
- package/lib/esm/errors.d.ts +27 -13
- package/lib/esm/errors.js +36 -8
- package/lib/esm/offers/Offer.d.ts +50 -0
- package/lib/esm/offers/Offer.js +53 -0
- package/lib/esm/offers/OfferUtils.d.ts +108 -0
- package/lib/esm/offers/OfferUtils.js +117 -1
- package/lib/esm/position/PositionUtils.js +36 -12
- package/package.json +4 -4
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal Installed Midnight SDK package version. */
|
|
2
|
-
export declare const MIDNIGHT_SDK_VERSION = "2.1.0
|
|
2
|
+
export declare const MIDNIGHT_SDK_VERSION = "2.1.0";
|
package/lib/cjs/errors.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { InvalidPositionAccrualStateError as SharedInvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError as SharedInvalidPositionAccrualTimestampError, InvalidPositionLossFactorError as SharedInvalidPositionLossFactorError } from "@morpho-org/morpho-ts";
|
|
2
1
|
import type { Address } from "viem";
|
|
3
2
|
import type { MempoolPayloadValidationIssue } from "./api/types.js";
|
|
4
3
|
/**
|
|
@@ -71,27 +70,42 @@ export declare class SettlementFeeExceedsPriceError extends Error {
|
|
|
71
70
|
/**
|
|
72
71
|
* Thrown when a local position accrual is requested for an impossible timestamp.
|
|
73
72
|
*
|
|
74
|
-
* @
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { InvalidPositionAccrualTimestampError } from "@morpho-org/midnight-sdk";
|
|
76
|
+
*
|
|
77
|
+
* throw new InvalidPositionAccrualTimestampError(1n, 2n);
|
|
78
|
+
* ```
|
|
75
79
|
*/
|
|
76
|
-
export declare
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
export declare class InvalidPositionAccrualTimestampError extends Error {
|
|
81
|
+
constructor(timestamp: bigint, lastAccrual: bigint);
|
|
82
|
+
}
|
|
79
83
|
/**
|
|
80
84
|
* Thrown when a local position accrual sees a market loss factor older than the position.
|
|
81
85
|
*
|
|
82
|
-
* @
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* import { InvalidPositionLossFactorError } from "@morpho-org/midnight-sdk";
|
|
89
|
+
*
|
|
90
|
+
* throw new InvalidPositionLossFactorError(1n, 2n);
|
|
91
|
+
* ```
|
|
83
92
|
*/
|
|
84
|
-
export declare
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
export declare class InvalidPositionLossFactorError extends Error {
|
|
94
|
+
constructor(marketLossFactor: bigint, positionLossFactor: bigint);
|
|
95
|
+
}
|
|
87
96
|
/**
|
|
88
97
|
* Thrown when local position accrual inputs violate Midnight accounting invariants.
|
|
89
98
|
*
|
|
90
|
-
* @
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import { InvalidPositionAccrualStateError } from "@morpho-org/midnight-sdk";
|
|
102
|
+
*
|
|
103
|
+
* throw new InvalidPositionAccrualStateError("Pending fee exceeds credit.");
|
|
104
|
+
* ```
|
|
91
105
|
*/
|
|
92
|
-
export declare
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
export declare class InvalidPositionAccrualStateError extends Error {
|
|
107
|
+
constructor(reason: string);
|
|
108
|
+
}
|
|
95
109
|
/**
|
|
96
110
|
* Thrown when a market parameter cannot satisfy Midnight protocol rules.
|
|
97
111
|
*
|
package/lib/cjs/errors.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InvalidMidnightApiQuoteTargetError = exports.InvalidMidnightApiResponseError = exports.MidnightApiError = exports.InvalidEcrecoverSignatureVError = exports.InvalidTypedDataSignatureError = exports.MidnightMempoolValidationError = exports.ChainIdMismatchError = exports.RatifierV1TakerNotAllowedError = exports.InvalidRatifierV1AddressError = exports.InvalidRateRatifierV1TimeError = exports.InvalidRateRatifierV1TickError = exports.RateRatifierV1BoundOverflowError = exports.InvalidRateRatifierV1RateError = exports.InvalidTreeError = exports.InvalidTreeHeightError = exports.PayloadDecodeError = exports.InvalidOfferParameterError = exports.UnknownCollateralIndexError = exports.InvalidMarketParameterError = exports.InvalidPositionAccrualStateError = exports.InvalidPositionLossFactorError = exports.InvalidPositionAccrualTimestampError = exports.SettlementFeeExceedsPriceError = exports.InvalidTickSpacingError = exports.PriceGreaterThanOneError = exports.TickOutOfRangeError = exports.InvalidOfferGroupError = void 0;
|
|
4
|
-
const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
5
4
|
/**
|
|
6
5
|
* Thrown when a Midnight offer group violates protocol-level group mechanics.
|
|
7
6
|
*
|
|
@@ -90,25 +89,57 @@ class SettlementFeeExceedsPriceError extends Error {
|
|
|
90
89
|
}
|
|
91
90
|
}
|
|
92
91
|
exports.SettlementFeeExceedsPriceError = SettlementFeeExceedsPriceError;
|
|
93
|
-
// Temporary compatibility exception for these shared morpho-ts errors.
|
|
94
92
|
/**
|
|
95
93
|
* Thrown when a local position accrual is requested for an impossible timestamp.
|
|
96
94
|
*
|
|
97
|
-
* @
|
|
95
|
+
* @example
|
|
96
|
+
* ```ts
|
|
97
|
+
* import { InvalidPositionAccrualTimestampError } from "@morpho-org/midnight-sdk";
|
|
98
|
+
*
|
|
99
|
+
* throw new InvalidPositionAccrualTimestampError(1n, 2n);
|
|
100
|
+
* ```
|
|
98
101
|
*/
|
|
99
|
-
|
|
102
|
+
class InvalidPositionAccrualTimestampError extends Error {
|
|
103
|
+
constructor(timestamp, lastAccrual) {
|
|
104
|
+
super(`Position accrual timestamp "${timestamp}" is before last accrual "${lastAccrual}". Use a timestamp greater than or equal to last accrual.`);
|
|
105
|
+
this.name = "InvalidPositionAccrualTimestampError";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.InvalidPositionAccrualTimestampError = InvalidPositionAccrualTimestampError;
|
|
100
109
|
/**
|
|
101
110
|
* Thrown when a local position accrual sees a market loss factor older than the position.
|
|
102
111
|
*
|
|
103
|
-
* @
|
|
112
|
+
* @example
|
|
113
|
+
* ```ts
|
|
114
|
+
* import { InvalidPositionLossFactorError } from "@morpho-org/midnight-sdk";
|
|
115
|
+
*
|
|
116
|
+
* throw new InvalidPositionLossFactorError(1n, 2n);
|
|
117
|
+
* ```
|
|
104
118
|
*/
|
|
105
|
-
|
|
119
|
+
class InvalidPositionLossFactorError extends Error {
|
|
120
|
+
constructor(marketLossFactor, positionLossFactor) {
|
|
121
|
+
super(`Market loss factor "${marketLossFactor}" is below position loss factor "${positionLossFactor}". Fetch a consistent market and position at the same block.`);
|
|
122
|
+
this.name = "InvalidPositionLossFactorError";
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.InvalidPositionLossFactorError = InvalidPositionLossFactorError;
|
|
106
126
|
/**
|
|
107
127
|
* Thrown when local position accrual inputs violate Midnight accounting invariants.
|
|
108
128
|
*
|
|
109
|
-
* @
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* import { InvalidPositionAccrualStateError } from "@morpho-org/midnight-sdk";
|
|
132
|
+
*
|
|
133
|
+
* throw new InvalidPositionAccrualStateError("Pending fee exceeds credit.");
|
|
134
|
+
* ```
|
|
110
135
|
*/
|
|
111
|
-
|
|
136
|
+
class InvalidPositionAccrualStateError extends Error {
|
|
137
|
+
constructor(reason) {
|
|
138
|
+
super(`Invalid Midnight position accrual state. ${reason}`);
|
|
139
|
+
this.name = "InvalidPositionAccrualStateError";
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
exports.InvalidPositionAccrualStateError = InvalidPositionAccrualStateError;
|
|
112
143
|
/**
|
|
113
144
|
* Thrown when a market parameter cannot satisfy Midnight protocol rules.
|
|
114
145
|
*
|
|
@@ -150,6 +150,7 @@ export declare class Offer {
|
|
|
150
150
|
readonly tick: bigint;
|
|
151
151
|
private cachedGroup;
|
|
152
152
|
private cachedHash;
|
|
153
|
+
private cachedOnchainHash;
|
|
153
154
|
/**
|
|
154
155
|
* Whether the group id was supplied at construction rather than derived.
|
|
155
156
|
*
|
|
@@ -329,6 +330,55 @@ export declare class Offer {
|
|
|
329
330
|
* ```
|
|
330
331
|
*/
|
|
331
332
|
get hash(): Hash;
|
|
333
|
+
/**
|
|
334
|
+
* Returns the on-chain offer identifier emitted by Midnight's `Take` event.
|
|
335
|
+
*
|
|
336
|
+
* This `keccak256(abi.encode(offer))` hash identifies offers on-chain and is
|
|
337
|
+
* distinct from `hash`, the typehash-prefixed ratifier hash.
|
|
338
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
339
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
340
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
341
|
+
* `Group.create` group.
|
|
342
|
+
*
|
|
343
|
+
* @returns The cached on-chain offer hash.
|
|
344
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
345
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* import { Offer } from "@morpho-org/midnight-sdk";
|
|
349
|
+
* import { zeroAddress } from "viem";
|
|
350
|
+
*
|
|
351
|
+
* const offer = Offer.create({
|
|
352
|
+
* market: {
|
|
353
|
+
* chainId: 8453,
|
|
354
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
355
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
356
|
+
* collateralParams: [
|
|
357
|
+
* {
|
|
358
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
359
|
+
* lltv: 770000000000000000n,
|
|
360
|
+
* liquidationCursor: 250000000000000000n,
|
|
361
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
362
|
+
* },
|
|
363
|
+
* ],
|
|
364
|
+
* maturity: 54_000n,
|
|
365
|
+
* rcfThreshold: 0n,
|
|
366
|
+
* enterGate: zeroAddress,
|
|
367
|
+
* liquidatorGate: zeroAddress,
|
|
368
|
+
* },
|
|
369
|
+
* buy: true,
|
|
370
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
371
|
+
* tick: 5_000n,
|
|
372
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
373
|
+
* expiry: 3_600n,
|
|
374
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
375
|
+
* maxUnits: 100n,
|
|
376
|
+
* });
|
|
377
|
+
* const offerHash = offer.onchainHash;
|
|
378
|
+
* console.log(offerHash);
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
get onchainHash(): Hash;
|
|
332
382
|
/**
|
|
333
383
|
* WAD zero-coupon price at this offer's tick.
|
|
334
384
|
*
|
package/lib/cjs/offers/Offer.js
CHANGED
|
@@ -71,6 +71,7 @@ class Offer {
|
|
|
71
71
|
tick;
|
|
72
72
|
cachedGroup;
|
|
73
73
|
cachedHash;
|
|
74
|
+
cachedOnchainHash;
|
|
74
75
|
/**
|
|
75
76
|
* Whether the group id was supplied at construction rather than derived.
|
|
76
77
|
*
|
|
@@ -281,6 +282,58 @@ class Offer {
|
|
|
281
282
|
this.cachedHash ??= OfferUtils_js_1.OfferUtils.hash(this);
|
|
282
283
|
return this.cachedHash;
|
|
283
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* Returns the on-chain offer identifier emitted by Midnight's `Take` event.
|
|
287
|
+
*
|
|
288
|
+
* This `keccak256(abi.encode(offer))` hash identifies offers on-chain and is
|
|
289
|
+
* distinct from `hash`, the typehash-prefixed ratifier hash.
|
|
290
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
291
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
292
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
293
|
+
* `Group.create` group.
|
|
294
|
+
*
|
|
295
|
+
* @returns The cached on-chain offer hash.
|
|
296
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
297
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
298
|
+
* @example
|
|
299
|
+
* ```ts
|
|
300
|
+
* import { Offer } from "@morpho-org/midnight-sdk";
|
|
301
|
+
* import { zeroAddress } from "viem";
|
|
302
|
+
*
|
|
303
|
+
* const offer = Offer.create({
|
|
304
|
+
* market: {
|
|
305
|
+
* chainId: 8453,
|
|
306
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
307
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
308
|
+
* collateralParams: [
|
|
309
|
+
* {
|
|
310
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
311
|
+
* lltv: 770000000000000000n,
|
|
312
|
+
* liquidationCursor: 250000000000000000n,
|
|
313
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
314
|
+
* },
|
|
315
|
+
* ],
|
|
316
|
+
* maturity: 54_000n,
|
|
317
|
+
* rcfThreshold: 0n,
|
|
318
|
+
* enterGate: zeroAddress,
|
|
319
|
+
* liquidatorGate: zeroAddress,
|
|
320
|
+
* },
|
|
321
|
+
* buy: true,
|
|
322
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
323
|
+
* tick: 5_000n,
|
|
324
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
325
|
+
* expiry: 3_600n,
|
|
326
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
327
|
+
* maxUnits: 100n,
|
|
328
|
+
* });
|
|
329
|
+
* const offerHash = offer.onchainHash;
|
|
330
|
+
* console.log(offerHash);
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
get onchainHash() {
|
|
334
|
+
this.cachedOnchainHash ??= OfferUtils_js_1.OfferUtils.onchainHash(this);
|
|
335
|
+
return this.cachedOnchainHash;
|
|
336
|
+
}
|
|
284
337
|
/**
|
|
285
338
|
* WAD zero-coupon price at this offer's tick.
|
|
286
339
|
*
|
|
@@ -160,6 +160,114 @@ export declare namespace OfferUtils {
|
|
|
160
160
|
* ```
|
|
161
161
|
*/
|
|
162
162
|
function hash(offer: IOffer & Required<Pick<IOffer, "group">>): Hash;
|
|
163
|
+
/**
|
|
164
|
+
* Computes the on-chain offer identifier from the supplied offer struct.
|
|
165
|
+
*
|
|
166
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
167
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
168
|
+
* `hashStruct` and `hash`, which produce the typehash-prefixed ratifier hash.
|
|
169
|
+
* Collaterals are hashed in the supplied order; Midnight rejects unsorted
|
|
170
|
+
* collateral params with `CollateralParamsNotSorted`, so pass a sorted struct,
|
|
171
|
+
* for example one returned by `toStruct`.
|
|
172
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
173
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
174
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
175
|
+
* `Group.create` group.
|
|
176
|
+
*
|
|
177
|
+
* @param offerStruct - ABI-compatible offer to hash without normalization.
|
|
178
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
179
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
180
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
184
|
+
* import { zeroAddress } from "viem";
|
|
185
|
+
*
|
|
186
|
+
* const offer = Offer.create({
|
|
187
|
+
* market: {
|
|
188
|
+
* chainId: 8453,
|
|
189
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
190
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
191
|
+
* collateralParams: [
|
|
192
|
+
* {
|
|
193
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
194
|
+
* lltv: 770000000000000000n,
|
|
195
|
+
* liquidationCursor: 250000000000000000n,
|
|
196
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
197
|
+
* },
|
|
198
|
+
* ],
|
|
199
|
+
* maturity: 54_000n,
|
|
200
|
+
* rcfThreshold: 0n,
|
|
201
|
+
* enterGate: zeroAddress,
|
|
202
|
+
* liquidatorGate: zeroAddress,
|
|
203
|
+
* },
|
|
204
|
+
* buy: true,
|
|
205
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
206
|
+
* tick: 5_000n,
|
|
207
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
208
|
+
* expiry: 3_600n,
|
|
209
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
210
|
+
* maxUnits: 100n,
|
|
211
|
+
* });
|
|
212
|
+
* const offerHash = OfferUtils.onchainHashStruct(
|
|
213
|
+
* OfferUtils.toStruct({ offer }),
|
|
214
|
+
* );
|
|
215
|
+
* console.log(offerHash);
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
function onchainHashStruct(offerStruct: OfferStruct): Hash;
|
|
219
|
+
/**
|
|
220
|
+
* Computes the on-chain offer identifier from an offer with a group id.
|
|
221
|
+
*
|
|
222
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
223
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
224
|
+
* `hash`, which returns the typehash-prefixed ratifier hash. `toStruct`
|
|
225
|
+
* normalizes the offer and sorts collateral params as required by Midnight.
|
|
226
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
227
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
228
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
229
|
+
* `Group.create` group.
|
|
230
|
+
*
|
|
231
|
+
* @param offer - Offer with the protocol group id encoded in its struct.
|
|
232
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
233
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
234
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
235
|
+
* @example
|
|
236
|
+
* ```ts
|
|
237
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
238
|
+
* import { zeroAddress } from "viem";
|
|
239
|
+
*
|
|
240
|
+
* const offer = Offer.create({
|
|
241
|
+
* market: {
|
|
242
|
+
* chainId: 8453,
|
|
243
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
244
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
245
|
+
* collateralParams: [
|
|
246
|
+
* {
|
|
247
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
248
|
+
* lltv: 770000000000000000n,
|
|
249
|
+
* liquidationCursor: 250000000000000000n,
|
|
250
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
251
|
+
* },
|
|
252
|
+
* ],
|
|
253
|
+
* maturity: 54_000n,
|
|
254
|
+
* rcfThreshold: 0n,
|
|
255
|
+
* enterGate: zeroAddress,
|
|
256
|
+
* liquidatorGate: zeroAddress,
|
|
257
|
+
* },
|
|
258
|
+
* buy: true,
|
|
259
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
260
|
+
* tick: 5_000n,
|
|
261
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
262
|
+
* expiry: 3_600n,
|
|
263
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
264
|
+
* maxUnits: 100n,
|
|
265
|
+
* });
|
|
266
|
+
* const offerHash = OfferUtils.onchainHash(offer);
|
|
267
|
+
* console.log(offerHash);
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
function onchainHash(offer: IOffer & Required<Pick<IOffer, "group">>): Hash;
|
|
163
271
|
/**
|
|
164
272
|
* Computes the offer hash used to derive a content-addressed group id.
|
|
165
273
|
*
|
|
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.OfferUtils = void 0;
|
|
4
4
|
const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
5
5
|
const viem_1 = require("viem");
|
|
6
|
+
const abis_js_1 = require("../abis.js");
|
|
6
7
|
const constants_js_1 = require("../constants.js");
|
|
7
8
|
const errors_js_1 = require("../errors.js");
|
|
8
9
|
const index_js_1 = require("../market/index.js");
|
|
9
10
|
const index_js_2 = require("../math/index.js");
|
|
10
11
|
const Offer_js_1 = require("./Offer.js");
|
|
12
|
+
const takeOfferParam = (0, viem_1.getAbiItem)({ abi: abis_js_1.midnightAbi, name: "take" }).inputs[0];
|
|
11
13
|
const offerHashParams = [
|
|
12
14
|
{ name: "typehash", type: "bytes32" },
|
|
13
15
|
{ name: "marketHash", type: "bytes32" },
|
|
@@ -226,6 +228,120 @@ var OfferUtils;
|
|
|
226
228
|
return hashStruct(toStruct({ offer }));
|
|
227
229
|
}
|
|
228
230
|
OfferUtils.hash = hash;
|
|
231
|
+
/**
|
|
232
|
+
* Computes the on-chain offer identifier from the supplied offer struct.
|
|
233
|
+
*
|
|
234
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
235
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
236
|
+
* `hashStruct` and `hash`, which produce the typehash-prefixed ratifier hash.
|
|
237
|
+
* Collaterals are hashed in the supplied order; Midnight rejects unsorted
|
|
238
|
+
* collateral params with `CollateralParamsNotSorted`, so pass a sorted struct,
|
|
239
|
+
* for example one returned by `toStruct`.
|
|
240
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
241
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
242
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
243
|
+
* `Group.create` group.
|
|
244
|
+
*
|
|
245
|
+
* @param offerStruct - ABI-compatible offer to hash without normalization.
|
|
246
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
247
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
248
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
249
|
+
* @example
|
|
250
|
+
* ```ts
|
|
251
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
252
|
+
* import { zeroAddress } from "viem";
|
|
253
|
+
*
|
|
254
|
+
* const offer = Offer.create({
|
|
255
|
+
* market: {
|
|
256
|
+
* chainId: 8453,
|
|
257
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
258
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
259
|
+
* collateralParams: [
|
|
260
|
+
* {
|
|
261
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
262
|
+
* lltv: 770000000000000000n,
|
|
263
|
+
* liquidationCursor: 250000000000000000n,
|
|
264
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
265
|
+
* },
|
|
266
|
+
* ],
|
|
267
|
+
* maturity: 54_000n,
|
|
268
|
+
* rcfThreshold: 0n,
|
|
269
|
+
* enterGate: zeroAddress,
|
|
270
|
+
* liquidatorGate: zeroAddress,
|
|
271
|
+
* },
|
|
272
|
+
* buy: true,
|
|
273
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
274
|
+
* tick: 5_000n,
|
|
275
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
276
|
+
* expiry: 3_600n,
|
|
277
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
278
|
+
* maxUnits: 100n,
|
|
279
|
+
* });
|
|
280
|
+
* const offerHash = OfferUtils.onchainHashStruct(
|
|
281
|
+
* OfferUtils.toStruct({ offer }),
|
|
282
|
+
* );
|
|
283
|
+
* console.log(offerHash);
|
|
284
|
+
* ```
|
|
285
|
+
*/
|
|
286
|
+
function onchainHashStruct(offerStruct) {
|
|
287
|
+
return (0, viem_1.keccak256)((0, viem_1.encodeAbiParameters)([takeOfferParam], [offerStruct]));
|
|
288
|
+
}
|
|
289
|
+
OfferUtils.onchainHashStruct = onchainHashStruct;
|
|
290
|
+
/**
|
|
291
|
+
* Computes the on-chain offer identifier from an offer with a group id.
|
|
292
|
+
*
|
|
293
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
294
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
295
|
+
* `hash`, which returns the typehash-prefixed ratifier hash. `toStruct`
|
|
296
|
+
* normalizes the offer and sorts collateral params as required by Midnight.
|
|
297
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
298
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
299
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
300
|
+
* `Group.create` group.
|
|
301
|
+
*
|
|
302
|
+
* @param offer - Offer with the protocol group id encoded in its struct.
|
|
303
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
304
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
305
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
309
|
+
* import { zeroAddress } from "viem";
|
|
310
|
+
*
|
|
311
|
+
* const offer = Offer.create({
|
|
312
|
+
* market: {
|
|
313
|
+
* chainId: 8453,
|
|
314
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
315
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
316
|
+
* collateralParams: [
|
|
317
|
+
* {
|
|
318
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
319
|
+
* lltv: 770000000000000000n,
|
|
320
|
+
* liquidationCursor: 250000000000000000n,
|
|
321
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
322
|
+
* },
|
|
323
|
+
* ],
|
|
324
|
+
* maturity: 54_000n,
|
|
325
|
+
* rcfThreshold: 0n,
|
|
326
|
+
* enterGate: zeroAddress,
|
|
327
|
+
* liquidatorGate: zeroAddress,
|
|
328
|
+
* },
|
|
329
|
+
* buy: true,
|
|
330
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
331
|
+
* tick: 5_000n,
|
|
332
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
333
|
+
* expiry: 3_600n,
|
|
334
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
335
|
+
* maxUnits: 100n,
|
|
336
|
+
* });
|
|
337
|
+
* const offerHash = OfferUtils.onchainHash(offer);
|
|
338
|
+
* console.log(offerHash);
|
|
339
|
+
* ```
|
|
340
|
+
*/
|
|
341
|
+
function onchainHash(offer) {
|
|
342
|
+
return onchainHashStruct(toStruct({ offer }));
|
|
343
|
+
}
|
|
344
|
+
OfferUtils.onchainHash = onchainHash;
|
|
229
345
|
/**
|
|
230
346
|
* Computes the offer hash used to derive a content-addressed group id.
|
|
231
347
|
*
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PositionUtils = void 0;
|
|
4
4
|
const morpho_ts_1 = require("@morpho-org/morpho-ts");
|
|
5
|
+
const errors_js_1 = require("../errors.js");
|
|
5
6
|
/**
|
|
6
7
|
* Domain helpers for Midnight positions.
|
|
7
8
|
*
|
|
@@ -134,17 +135,40 @@ var PositionUtils;
|
|
|
134
135
|
*/
|
|
135
136
|
function accrueInterest(params) {
|
|
136
137
|
const timestamp = BigInt(params.timestamp);
|
|
138
|
+
const credit = BigInt(params.position.credit);
|
|
139
|
+
const pendingFee = BigInt(params.position.pendingFee);
|
|
140
|
+
const lastLossFactor = BigInt(params.position.lastLossFactor);
|
|
141
|
+
const lastAccrual = BigInt(params.position.lastAccrual);
|
|
137
142
|
const marketLossFactor = BigInt(params.market.lossFactor);
|
|
143
|
+
if (timestamp < lastAccrual) {
|
|
144
|
+
throw new errors_js_1.InvalidPositionAccrualTimestampError(timestamp, lastAccrual);
|
|
145
|
+
}
|
|
146
|
+
if (marketLossFactor < lastLossFactor) {
|
|
147
|
+
throw new errors_js_1.InvalidPositionLossFactorError(marketLossFactor, lastLossFactor);
|
|
148
|
+
}
|
|
149
|
+
if (pendingFee > credit) {
|
|
150
|
+
throw new errors_js_1.InvalidPositionAccrualStateError("Pending fee must be less than or equal to credit.");
|
|
151
|
+
}
|
|
152
|
+
const postSlashCredit = lastLossFactor < morpho_ts_1.MathLib.MAX_UINT_128
|
|
153
|
+
? morpho_ts_1.MathLib.mulDivDown(credit, morpho_ts_1.MathLib.MAX_UINT_128 - marketLossFactor, morpho_ts_1.MathLib.MAX_UINT_128 - lastLossFactor)
|
|
154
|
+
: 0n;
|
|
155
|
+
if (postSlashCredit > credit) {
|
|
156
|
+
throw new errors_js_1.InvalidPositionAccrualStateError("Post-slash credit cannot exceed stored credit.");
|
|
157
|
+
}
|
|
158
|
+
const creditDecrease = credit - postSlashCredit;
|
|
159
|
+
const pendingFeeDecrease = credit > 0n ? morpho_ts_1.MathLib.mulDivUp(pendingFee, creditDecrease, credit) : 0n;
|
|
160
|
+
if (pendingFeeDecrease > pendingFee) {
|
|
161
|
+
throw new errors_js_1.InvalidPositionAccrualStateError("Pending-fee decrease cannot exceed pending fee.");
|
|
162
|
+
}
|
|
163
|
+
const postSlashPendingFee = pendingFee - pendingFeeDecrease;
|
|
138
164
|
const maturity = BigInt(params.market.params.maturity);
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
timestamp,
|
|
147
|
-
});
|
|
165
|
+
const accrualEnd = timestamp < maturity ? timestamp : maturity;
|
|
166
|
+
const accruedFee = lastAccrual < maturity
|
|
167
|
+
? morpho_ts_1.MathLib.mulDivDown(postSlashPendingFee, accrualEnd - lastAccrual, maturity - lastAccrual)
|
|
168
|
+
: 0n;
|
|
169
|
+
if (accruedFee > postSlashCredit || accruedFee > postSlashPendingFee) {
|
|
170
|
+
throw new errors_js_1.InvalidPositionAccrualStateError("Accrued fee cannot exceed post-slash credit or pending fee.");
|
|
171
|
+
}
|
|
148
172
|
const collateral = params.position.collateral.map((assets) => BigInt(assets));
|
|
149
173
|
const collateralParams = params.market.params.collateralParams.map((collateralParam) => ({
|
|
150
174
|
token: collateralParam.token,
|
|
@@ -175,8 +199,8 @@ var PositionUtils;
|
|
|
175
199
|
position: {
|
|
176
200
|
user: params.position.user,
|
|
177
201
|
marketId: params.position.marketId,
|
|
178
|
-
credit,
|
|
179
|
-
pendingFee,
|
|
202
|
+
credit: postSlashCredit - accruedFee,
|
|
203
|
+
pendingFee: postSlashPendingFee - accruedFee,
|
|
180
204
|
lastLossFactor: marketLossFactor,
|
|
181
205
|
lastAccrual: timestamp,
|
|
182
206
|
debt: BigInt(params.position.debt),
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @internal Installed Midnight SDK package version. */
|
|
2
|
-
export declare const MIDNIGHT_SDK_VERSION = "2.1.0
|
|
2
|
+
export declare const MIDNIGHT_SDK_VERSION = "2.1.0";
|
package/lib/esm/errors.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { InvalidPositionAccrualStateError as SharedInvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError as SharedInvalidPositionAccrualTimestampError, InvalidPositionLossFactorError as SharedInvalidPositionLossFactorError } from "@morpho-org/morpho-ts";
|
|
2
1
|
import type { Address } from "viem";
|
|
3
2
|
import type { MempoolPayloadValidationIssue } from "./api/types.js";
|
|
4
3
|
/**
|
|
@@ -71,27 +70,42 @@ export declare class SettlementFeeExceedsPriceError extends Error {
|
|
|
71
70
|
/**
|
|
72
71
|
* Thrown when a local position accrual is requested for an impossible timestamp.
|
|
73
72
|
*
|
|
74
|
-
* @
|
|
73
|
+
* @example
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { InvalidPositionAccrualTimestampError } from "@morpho-org/midnight-sdk";
|
|
76
|
+
*
|
|
77
|
+
* throw new InvalidPositionAccrualTimestampError(1n, 2n);
|
|
78
|
+
* ```
|
|
75
79
|
*/
|
|
76
|
-
export declare
|
|
77
|
-
|
|
78
|
-
|
|
80
|
+
export declare class InvalidPositionAccrualTimestampError extends Error {
|
|
81
|
+
constructor(timestamp: bigint, lastAccrual: bigint);
|
|
82
|
+
}
|
|
79
83
|
/**
|
|
80
84
|
* Thrown when a local position accrual sees a market loss factor older than the position.
|
|
81
85
|
*
|
|
82
|
-
* @
|
|
86
|
+
* @example
|
|
87
|
+
* ```ts
|
|
88
|
+
* import { InvalidPositionLossFactorError } from "@morpho-org/midnight-sdk";
|
|
89
|
+
*
|
|
90
|
+
* throw new InvalidPositionLossFactorError(1n, 2n);
|
|
91
|
+
* ```
|
|
83
92
|
*/
|
|
84
|
-
export declare
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
export declare class InvalidPositionLossFactorError extends Error {
|
|
94
|
+
constructor(marketLossFactor: bigint, positionLossFactor: bigint);
|
|
95
|
+
}
|
|
87
96
|
/**
|
|
88
97
|
* Thrown when local position accrual inputs violate Midnight accounting invariants.
|
|
89
98
|
*
|
|
90
|
-
* @
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import { InvalidPositionAccrualStateError } from "@morpho-org/midnight-sdk";
|
|
102
|
+
*
|
|
103
|
+
* throw new InvalidPositionAccrualStateError("Pending fee exceeds credit.");
|
|
104
|
+
* ```
|
|
91
105
|
*/
|
|
92
|
-
export declare
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
export declare class InvalidPositionAccrualStateError extends Error {
|
|
107
|
+
constructor(reason: string);
|
|
108
|
+
}
|
|
95
109
|
/**
|
|
96
110
|
* Thrown when a market parameter cannot satisfy Midnight protocol rules.
|
|
97
111
|
*
|
package/lib/esm/errors.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { InvalidPositionAccrualStateError as SharedInvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError as SharedInvalidPositionAccrualTimestampError, InvalidPositionLossFactorError as SharedInvalidPositionLossFactorError, } from "@morpho-org/morpho-ts";
|
|
2
1
|
/**
|
|
3
2
|
* Thrown when a Midnight offer group violates protocol-level group mechanics.
|
|
4
3
|
*
|
|
@@ -82,25 +81,54 @@ export class SettlementFeeExceedsPriceError extends Error {
|
|
|
82
81
|
this.name = "SettlementFeeExceedsPriceError";
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
|
-
// Temporary compatibility exception for these shared morpho-ts errors.
|
|
86
84
|
/**
|
|
87
85
|
* Thrown when a local position accrual is requested for an impossible timestamp.
|
|
88
86
|
*
|
|
89
|
-
* @
|
|
87
|
+
* @example
|
|
88
|
+
* ```ts
|
|
89
|
+
* import { InvalidPositionAccrualTimestampError } from "@morpho-org/midnight-sdk";
|
|
90
|
+
*
|
|
91
|
+
* throw new InvalidPositionAccrualTimestampError(1n, 2n);
|
|
92
|
+
* ```
|
|
90
93
|
*/
|
|
91
|
-
export
|
|
94
|
+
export class InvalidPositionAccrualTimestampError extends Error {
|
|
95
|
+
constructor(timestamp, lastAccrual) {
|
|
96
|
+
super(`Position accrual timestamp "${timestamp}" is before last accrual "${lastAccrual}". Use a timestamp greater than or equal to last accrual.`);
|
|
97
|
+
this.name = "InvalidPositionAccrualTimestampError";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
92
100
|
/**
|
|
93
101
|
* Thrown when a local position accrual sees a market loss factor older than the position.
|
|
94
102
|
*
|
|
95
|
-
* @
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* import { InvalidPositionLossFactorError } from "@morpho-org/midnight-sdk";
|
|
106
|
+
*
|
|
107
|
+
* throw new InvalidPositionLossFactorError(1n, 2n);
|
|
108
|
+
* ```
|
|
96
109
|
*/
|
|
97
|
-
export
|
|
110
|
+
export class InvalidPositionLossFactorError extends Error {
|
|
111
|
+
constructor(marketLossFactor, positionLossFactor) {
|
|
112
|
+
super(`Market loss factor "${marketLossFactor}" is below position loss factor "${positionLossFactor}". Fetch a consistent market and position at the same block.`);
|
|
113
|
+
this.name = "InvalidPositionLossFactorError";
|
|
114
|
+
}
|
|
115
|
+
}
|
|
98
116
|
/**
|
|
99
117
|
* Thrown when local position accrual inputs violate Midnight accounting invariants.
|
|
100
118
|
*
|
|
101
|
-
* @
|
|
119
|
+
* @example
|
|
120
|
+
* ```ts
|
|
121
|
+
* import { InvalidPositionAccrualStateError } from "@morpho-org/midnight-sdk";
|
|
122
|
+
*
|
|
123
|
+
* throw new InvalidPositionAccrualStateError("Pending fee exceeds credit.");
|
|
124
|
+
* ```
|
|
102
125
|
*/
|
|
103
|
-
export
|
|
126
|
+
export class InvalidPositionAccrualStateError extends Error {
|
|
127
|
+
constructor(reason) {
|
|
128
|
+
super(`Invalid Midnight position accrual state. ${reason}`);
|
|
129
|
+
this.name = "InvalidPositionAccrualStateError";
|
|
130
|
+
}
|
|
131
|
+
}
|
|
104
132
|
/**
|
|
105
133
|
* Thrown when a market parameter cannot satisfy Midnight protocol rules.
|
|
106
134
|
*
|
|
@@ -150,6 +150,7 @@ export declare class Offer {
|
|
|
150
150
|
readonly tick: bigint;
|
|
151
151
|
private cachedGroup;
|
|
152
152
|
private cachedHash;
|
|
153
|
+
private cachedOnchainHash;
|
|
153
154
|
/**
|
|
154
155
|
* Whether the group id was supplied at construction rather than derived.
|
|
155
156
|
*
|
|
@@ -329,6 +330,55 @@ export declare class Offer {
|
|
|
329
330
|
* ```
|
|
330
331
|
*/
|
|
331
332
|
get hash(): Hash;
|
|
333
|
+
/**
|
|
334
|
+
* Returns the on-chain offer identifier emitted by Midnight's `Take` event.
|
|
335
|
+
*
|
|
336
|
+
* This `keccak256(abi.encode(offer))` hash identifies offers on-chain and is
|
|
337
|
+
* distinct from `hash`, the typehash-prefixed ratifier hash.
|
|
338
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
339
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
340
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
341
|
+
* `Group.create` group.
|
|
342
|
+
*
|
|
343
|
+
* @returns The cached on-chain offer hash.
|
|
344
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
345
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* import { Offer } from "@morpho-org/midnight-sdk";
|
|
349
|
+
* import { zeroAddress } from "viem";
|
|
350
|
+
*
|
|
351
|
+
* const offer = Offer.create({
|
|
352
|
+
* market: {
|
|
353
|
+
* chainId: 8453,
|
|
354
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
355
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
356
|
+
* collateralParams: [
|
|
357
|
+
* {
|
|
358
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
359
|
+
* lltv: 770000000000000000n,
|
|
360
|
+
* liquidationCursor: 250000000000000000n,
|
|
361
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
362
|
+
* },
|
|
363
|
+
* ],
|
|
364
|
+
* maturity: 54_000n,
|
|
365
|
+
* rcfThreshold: 0n,
|
|
366
|
+
* enterGate: zeroAddress,
|
|
367
|
+
* liquidatorGate: zeroAddress,
|
|
368
|
+
* },
|
|
369
|
+
* buy: true,
|
|
370
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
371
|
+
* tick: 5_000n,
|
|
372
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
373
|
+
* expiry: 3_600n,
|
|
374
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
375
|
+
* maxUnits: 100n,
|
|
376
|
+
* });
|
|
377
|
+
* const offerHash = offer.onchainHash;
|
|
378
|
+
* console.log(offerHash);
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
get onchainHash(): Hash;
|
|
332
382
|
/**
|
|
333
383
|
* WAD zero-coupon price at this offer's tick.
|
|
334
384
|
*
|
package/lib/esm/offers/Offer.js
CHANGED
|
@@ -68,6 +68,7 @@ export class Offer {
|
|
|
68
68
|
tick;
|
|
69
69
|
cachedGroup;
|
|
70
70
|
cachedHash;
|
|
71
|
+
cachedOnchainHash;
|
|
71
72
|
/**
|
|
72
73
|
* Whether the group id was supplied at construction rather than derived.
|
|
73
74
|
*
|
|
@@ -278,6 +279,58 @@ export class Offer {
|
|
|
278
279
|
this.cachedHash ??= OfferUtils.hash(this);
|
|
279
280
|
return this.cachedHash;
|
|
280
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* Returns the on-chain offer identifier emitted by Midnight's `Take` event.
|
|
284
|
+
*
|
|
285
|
+
* This `keccak256(abi.encode(offer))` hash identifies offers on-chain and is
|
|
286
|
+
* distinct from `hash`, the typehash-prefixed ratifier hash.
|
|
287
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
288
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
289
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
290
|
+
* `Group.create` group.
|
|
291
|
+
*
|
|
292
|
+
* @returns The cached on-chain offer hash.
|
|
293
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
294
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
295
|
+
* @example
|
|
296
|
+
* ```ts
|
|
297
|
+
* import { Offer } from "@morpho-org/midnight-sdk";
|
|
298
|
+
* import { zeroAddress } from "viem";
|
|
299
|
+
*
|
|
300
|
+
* const offer = Offer.create({
|
|
301
|
+
* market: {
|
|
302
|
+
* chainId: 8453,
|
|
303
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
304
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
305
|
+
* collateralParams: [
|
|
306
|
+
* {
|
|
307
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
308
|
+
* lltv: 770000000000000000n,
|
|
309
|
+
* liquidationCursor: 250000000000000000n,
|
|
310
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
311
|
+
* },
|
|
312
|
+
* ],
|
|
313
|
+
* maturity: 54_000n,
|
|
314
|
+
* rcfThreshold: 0n,
|
|
315
|
+
* enterGate: zeroAddress,
|
|
316
|
+
* liquidatorGate: zeroAddress,
|
|
317
|
+
* },
|
|
318
|
+
* buy: true,
|
|
319
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
320
|
+
* tick: 5_000n,
|
|
321
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
322
|
+
* expiry: 3_600n,
|
|
323
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
324
|
+
* maxUnits: 100n,
|
|
325
|
+
* });
|
|
326
|
+
* const offerHash = offer.onchainHash;
|
|
327
|
+
* console.log(offerHash);
|
|
328
|
+
* ```
|
|
329
|
+
*/
|
|
330
|
+
get onchainHash() {
|
|
331
|
+
this.cachedOnchainHash ??= OfferUtils.onchainHash(this);
|
|
332
|
+
return this.cachedOnchainHash;
|
|
333
|
+
}
|
|
281
334
|
/**
|
|
282
335
|
* WAD zero-coupon price at this offer's tick.
|
|
283
336
|
*
|
|
@@ -160,6 +160,114 @@ export declare namespace OfferUtils {
|
|
|
160
160
|
* ```
|
|
161
161
|
*/
|
|
162
162
|
function hash(offer: IOffer & Required<Pick<IOffer, "group">>): Hash;
|
|
163
|
+
/**
|
|
164
|
+
* Computes the on-chain offer identifier from the supplied offer struct.
|
|
165
|
+
*
|
|
166
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
167
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
168
|
+
* `hashStruct` and `hash`, which produce the typehash-prefixed ratifier hash.
|
|
169
|
+
* Collaterals are hashed in the supplied order; Midnight rejects unsorted
|
|
170
|
+
* collateral params with `CollateralParamsNotSorted`, so pass a sorted struct,
|
|
171
|
+
* for example one returned by `toStruct`.
|
|
172
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
173
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
174
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
175
|
+
* `Group.create` group.
|
|
176
|
+
*
|
|
177
|
+
* @param offerStruct - ABI-compatible offer to hash without normalization.
|
|
178
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
179
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
180
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
181
|
+
* @example
|
|
182
|
+
* ```ts
|
|
183
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
184
|
+
* import { zeroAddress } from "viem";
|
|
185
|
+
*
|
|
186
|
+
* const offer = Offer.create({
|
|
187
|
+
* market: {
|
|
188
|
+
* chainId: 8453,
|
|
189
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
190
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
191
|
+
* collateralParams: [
|
|
192
|
+
* {
|
|
193
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
194
|
+
* lltv: 770000000000000000n,
|
|
195
|
+
* liquidationCursor: 250000000000000000n,
|
|
196
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
197
|
+
* },
|
|
198
|
+
* ],
|
|
199
|
+
* maturity: 54_000n,
|
|
200
|
+
* rcfThreshold: 0n,
|
|
201
|
+
* enterGate: zeroAddress,
|
|
202
|
+
* liquidatorGate: zeroAddress,
|
|
203
|
+
* },
|
|
204
|
+
* buy: true,
|
|
205
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
206
|
+
* tick: 5_000n,
|
|
207
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
208
|
+
* expiry: 3_600n,
|
|
209
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
210
|
+
* maxUnits: 100n,
|
|
211
|
+
* });
|
|
212
|
+
* const offerHash = OfferUtils.onchainHashStruct(
|
|
213
|
+
* OfferUtils.toStruct({ offer }),
|
|
214
|
+
* );
|
|
215
|
+
* console.log(offerHash);
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
function onchainHashStruct(offerStruct: OfferStruct): Hash;
|
|
219
|
+
/**
|
|
220
|
+
* Computes the on-chain offer identifier from an offer with a group id.
|
|
221
|
+
*
|
|
222
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
223
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
224
|
+
* `hash`, which returns the typehash-prefixed ratifier hash. `toStruct`
|
|
225
|
+
* normalizes the offer and sorts collateral params as required by Midnight.
|
|
226
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
227
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
228
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
229
|
+
* `Group.create` group.
|
|
230
|
+
*
|
|
231
|
+
* @param offer - Offer with the protocol group id encoded in its struct.
|
|
232
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
233
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
234
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
235
|
+
* @example
|
|
236
|
+
* ```ts
|
|
237
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
238
|
+
* import { zeroAddress } from "viem";
|
|
239
|
+
*
|
|
240
|
+
* const offer = Offer.create({
|
|
241
|
+
* market: {
|
|
242
|
+
* chainId: 8453,
|
|
243
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
244
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
245
|
+
* collateralParams: [
|
|
246
|
+
* {
|
|
247
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
248
|
+
* lltv: 770000000000000000n,
|
|
249
|
+
* liquidationCursor: 250000000000000000n,
|
|
250
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
251
|
+
* },
|
|
252
|
+
* ],
|
|
253
|
+
* maturity: 54_000n,
|
|
254
|
+
* rcfThreshold: 0n,
|
|
255
|
+
* enterGate: zeroAddress,
|
|
256
|
+
* liquidatorGate: zeroAddress,
|
|
257
|
+
* },
|
|
258
|
+
* buy: true,
|
|
259
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
260
|
+
* tick: 5_000n,
|
|
261
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
262
|
+
* expiry: 3_600n,
|
|
263
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
264
|
+
* maxUnits: 100n,
|
|
265
|
+
* });
|
|
266
|
+
* const offerHash = OfferUtils.onchainHash(offer);
|
|
267
|
+
* console.log(offerHash);
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
function onchainHash(offer: IOffer & Required<Pick<IOffer, "group">>): Hash;
|
|
163
271
|
/**
|
|
164
272
|
* Computes the offer hash used to derive a content-addressed group id.
|
|
165
273
|
*
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { assertNonNegative, DivisionByZeroError, MathLib, } from "@morpho-org/morpho-ts";
|
|
2
|
-
import { encodeAbiParameters, isAddressEqual, keccak256, zeroAddress, zeroHash, } from "viem";
|
|
2
|
+
import { encodeAbiParameters, getAbiItem, isAddressEqual, keccak256, zeroAddress, zeroHash, } from "viem";
|
|
3
|
+
import { midnightAbi } from "../abis.js";
|
|
3
4
|
import { DEFAULT_TICK_SPACING, MAX_OFFER_CAP, MAX_TICK, OFFER_TYPEHASH, } from "../constants.js";
|
|
4
5
|
import { InvalidOfferGroupError, InvalidOfferParameterError, } from "../errors.js";
|
|
5
6
|
import { Market, MarketParams, MarketUtils } from "../market/index.js";
|
|
6
7
|
import { TakeAmountsLib, TickLib } from "../math/index.js";
|
|
7
8
|
import { Offer, } from "./Offer.js";
|
|
9
|
+
const takeOfferParam = getAbiItem({ abi: midnightAbi, name: "take" }).inputs[0];
|
|
8
10
|
const offerHashParams = [
|
|
9
11
|
{ name: "typehash", type: "bytes32" },
|
|
10
12
|
{ name: "marketHash", type: "bytes32" },
|
|
@@ -223,6 +225,120 @@ export var OfferUtils;
|
|
|
223
225
|
return hashStruct(toStruct({ offer }));
|
|
224
226
|
}
|
|
225
227
|
OfferUtils.hash = hash;
|
|
228
|
+
/**
|
|
229
|
+
* Computes the on-chain offer identifier from the supplied offer struct.
|
|
230
|
+
*
|
|
231
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
232
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
233
|
+
* `hashStruct` and `hash`, which produce the typehash-prefixed ratifier hash.
|
|
234
|
+
* Collaterals are hashed in the supplied order; Midnight rejects unsorted
|
|
235
|
+
* collateral params with `CollateralParamsNotSorted`, so pass a sorted struct,
|
|
236
|
+
* for example one returned by `toStruct`.
|
|
237
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
238
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
239
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
240
|
+
* `Group.create` group.
|
|
241
|
+
*
|
|
242
|
+
* @param offerStruct - ABI-compatible offer to hash without normalization.
|
|
243
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
244
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
245
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
246
|
+
* @example
|
|
247
|
+
* ```ts
|
|
248
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
249
|
+
* import { zeroAddress } from "viem";
|
|
250
|
+
*
|
|
251
|
+
* const offer = Offer.create({
|
|
252
|
+
* market: {
|
|
253
|
+
* chainId: 8453,
|
|
254
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
255
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
256
|
+
* collateralParams: [
|
|
257
|
+
* {
|
|
258
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
259
|
+
* lltv: 770000000000000000n,
|
|
260
|
+
* liquidationCursor: 250000000000000000n,
|
|
261
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
262
|
+
* },
|
|
263
|
+
* ],
|
|
264
|
+
* maturity: 54_000n,
|
|
265
|
+
* rcfThreshold: 0n,
|
|
266
|
+
* enterGate: zeroAddress,
|
|
267
|
+
* liquidatorGate: zeroAddress,
|
|
268
|
+
* },
|
|
269
|
+
* buy: true,
|
|
270
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
271
|
+
* tick: 5_000n,
|
|
272
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
273
|
+
* expiry: 3_600n,
|
|
274
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
275
|
+
* maxUnits: 100n,
|
|
276
|
+
* });
|
|
277
|
+
* const offerHash = OfferUtils.onchainHashStruct(
|
|
278
|
+
* OfferUtils.toStruct({ offer }),
|
|
279
|
+
* );
|
|
280
|
+
* console.log(offerHash);
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
function onchainHashStruct(offerStruct) {
|
|
284
|
+
return keccak256(encodeAbiParameters([takeOfferParam], [offerStruct]));
|
|
285
|
+
}
|
|
286
|
+
OfferUtils.onchainHashStruct = onchainHashStruct;
|
|
287
|
+
/**
|
|
288
|
+
* Computes the on-chain offer identifier from an offer with a group id.
|
|
289
|
+
*
|
|
290
|
+
* This is `keccak256(abi.encode(offer))`, the hash emitted by Midnight's
|
|
291
|
+
* `Take` event and used to identify offers on-chain. It is distinct from
|
|
292
|
+
* `hash`, which returns the typehash-prefixed ratifier hash. `toStruct`
|
|
293
|
+
* normalizes the offer and sorts collateral params as required by Midnight.
|
|
294
|
+
* It matches a `Take` event only for the offer exactly as published. For
|
|
295
|
+
* RateRatifierV1 and PriceRatifierV1, hash the offers in the descriptor's
|
|
296
|
+
* `offers`: `buildDescriptor` replaces both the default group and a
|
|
297
|
+
* `Group.create` group.
|
|
298
|
+
*
|
|
299
|
+
* @param offer - Offer with the protocol group id encoded in its struct.
|
|
300
|
+
* @returns The offer hash emitted by Midnight's `Take` event.
|
|
301
|
+
* @throws {viem.InvalidAddressError} when an address has an invalid mixed-case checksum.
|
|
302
|
+
* @throws {viem.IntegerOutOfRangeError} when a uint field overflows its ABI size.
|
|
303
|
+
* @example
|
|
304
|
+
* ```ts
|
|
305
|
+
* import { Offer, OfferUtils } from "@morpho-org/midnight-sdk";
|
|
306
|
+
* import { zeroAddress } from "viem";
|
|
307
|
+
*
|
|
308
|
+
* const offer = Offer.create({
|
|
309
|
+
* market: {
|
|
310
|
+
* chainId: 8453,
|
|
311
|
+
* midnight: "0x0000000000000000000000000000000000001000",
|
|
312
|
+
* loanToken: "0x0000000000000000000000000000000000006000",
|
|
313
|
+
* collateralParams: [
|
|
314
|
+
* {
|
|
315
|
+
* token: "0x0000000000000000000000000000000000007000",
|
|
316
|
+
* lltv: 770000000000000000n,
|
|
317
|
+
* liquidationCursor: 250000000000000000n,
|
|
318
|
+
* oracle: "0x0000000000000000000000000000000000008000",
|
|
319
|
+
* },
|
|
320
|
+
* ],
|
|
321
|
+
* maturity: 54_000n,
|
|
322
|
+
* rcfThreshold: 0n,
|
|
323
|
+
* enterGate: zeroAddress,
|
|
324
|
+
* liquidatorGate: zeroAddress,
|
|
325
|
+
* },
|
|
326
|
+
* buy: true,
|
|
327
|
+
* maker: "0x0000000000000000000000000000000000009000",
|
|
328
|
+
* tick: 5_000n,
|
|
329
|
+
* group: "0x1111111111111111111111111111111111111111111111111111111111111111",
|
|
330
|
+
* expiry: 3_600n,
|
|
331
|
+
* ratifier: "0x0000000000000000000000000000000000004000",
|
|
332
|
+
* maxUnits: 100n,
|
|
333
|
+
* });
|
|
334
|
+
* const offerHash = OfferUtils.onchainHash(offer);
|
|
335
|
+
* console.log(offerHash);
|
|
336
|
+
* ```
|
|
337
|
+
*/
|
|
338
|
+
function onchainHash(offer) {
|
|
339
|
+
return onchainHashStruct(toStruct({ offer }));
|
|
340
|
+
}
|
|
341
|
+
OfferUtils.onchainHash = onchainHash;
|
|
226
342
|
/**
|
|
227
343
|
* Computes the offer hash used to derive a content-addressed group id.
|
|
228
344
|
*
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { MathLib
|
|
1
|
+
import { MathLib } from "@morpho-org/morpho-ts";
|
|
2
|
+
import { InvalidPositionAccrualStateError, InvalidPositionAccrualTimestampError, InvalidPositionLossFactorError, } from "../errors.js";
|
|
2
3
|
/**
|
|
3
4
|
* Domain helpers for Midnight positions.
|
|
4
5
|
*
|
|
@@ -131,17 +132,40 @@ export var PositionUtils;
|
|
|
131
132
|
*/
|
|
132
133
|
function accrueInterest(params) {
|
|
133
134
|
const timestamp = BigInt(params.timestamp);
|
|
135
|
+
const credit = BigInt(params.position.credit);
|
|
136
|
+
const pendingFee = BigInt(params.position.pendingFee);
|
|
137
|
+
const lastLossFactor = BigInt(params.position.lastLossFactor);
|
|
138
|
+
const lastAccrual = BigInt(params.position.lastAccrual);
|
|
134
139
|
const marketLossFactor = BigInt(params.market.lossFactor);
|
|
140
|
+
if (timestamp < lastAccrual) {
|
|
141
|
+
throw new InvalidPositionAccrualTimestampError(timestamp, lastAccrual);
|
|
142
|
+
}
|
|
143
|
+
if (marketLossFactor < lastLossFactor) {
|
|
144
|
+
throw new InvalidPositionLossFactorError(marketLossFactor, lastLossFactor);
|
|
145
|
+
}
|
|
146
|
+
if (pendingFee > credit) {
|
|
147
|
+
throw new InvalidPositionAccrualStateError("Pending fee must be less than or equal to credit.");
|
|
148
|
+
}
|
|
149
|
+
const postSlashCredit = lastLossFactor < MathLib.MAX_UINT_128
|
|
150
|
+
? MathLib.mulDivDown(credit, MathLib.MAX_UINT_128 - marketLossFactor, MathLib.MAX_UINT_128 - lastLossFactor)
|
|
151
|
+
: 0n;
|
|
152
|
+
if (postSlashCredit > credit) {
|
|
153
|
+
throw new InvalidPositionAccrualStateError("Post-slash credit cannot exceed stored credit.");
|
|
154
|
+
}
|
|
155
|
+
const creditDecrease = credit - postSlashCredit;
|
|
156
|
+
const pendingFeeDecrease = credit > 0n ? MathLib.mulDivUp(pendingFee, creditDecrease, credit) : 0n;
|
|
157
|
+
if (pendingFeeDecrease > pendingFee) {
|
|
158
|
+
throw new InvalidPositionAccrualStateError("Pending-fee decrease cannot exceed pending fee.");
|
|
159
|
+
}
|
|
160
|
+
const postSlashPendingFee = pendingFee - pendingFeeDecrease;
|
|
135
161
|
const maturity = BigInt(params.market.params.maturity);
|
|
136
|
-
const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
timestamp,
|
|
144
|
-
});
|
|
162
|
+
const accrualEnd = timestamp < maturity ? timestamp : maturity;
|
|
163
|
+
const accruedFee = lastAccrual < maturity
|
|
164
|
+
? MathLib.mulDivDown(postSlashPendingFee, accrualEnd - lastAccrual, maturity - lastAccrual)
|
|
165
|
+
: 0n;
|
|
166
|
+
if (accruedFee > postSlashCredit || accruedFee > postSlashPendingFee) {
|
|
167
|
+
throw new InvalidPositionAccrualStateError("Accrued fee cannot exceed post-slash credit or pending fee.");
|
|
168
|
+
}
|
|
145
169
|
const collateral = params.position.collateral.map((assets) => BigInt(assets));
|
|
146
170
|
const collateralParams = params.market.params.collateralParams.map((collateralParam) => ({
|
|
147
171
|
token: collateralParam.token,
|
|
@@ -172,8 +196,8 @@ export var PositionUtils;
|
|
|
172
196
|
position: {
|
|
173
197
|
user: params.position.user,
|
|
174
198
|
marketId: params.position.marketId,
|
|
175
|
-
credit,
|
|
176
|
-
pendingFee,
|
|
199
|
+
credit: postSlashCredit - accruedFee,
|
|
200
|
+
pendingFee: postSlashPendingFee - accruedFee,
|
|
177
201
|
lastLossFactor: marketLossFactor,
|
|
178
202
|
lastAccrual: timestamp,
|
|
179
203
|
debt: BigInt(params.position.debt),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@morpho-org/midnight-sdk",
|
|
3
3
|
"description": "Viem-based package for Morpho Midnight that exports protocol utilities, fetch helpers, and Midnight API utilities under a dedicated API subpath.",
|
|
4
|
-
"version": "2.1.0
|
|
4
|
+
"version": "2.1.0",
|
|
5
5
|
"author": "Morpho Association <contact@morpho.org>",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
"MIGRATION-v1-to-v2.md"
|
|
42
42
|
],
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@morpho-org/morpho-ts": "^4.
|
|
44
|
+
"@morpho-org/morpho-ts": "^2.8.0 || ^3.0.0 || ^4.0.0",
|
|
45
45
|
"viem": "^2.0.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@morpho-org/morpho-ts": "^4.
|
|
49
|
-
"@morpho-org/test": "^2.11.0
|
|
48
|
+
"@morpho-org/morpho-ts": "^4.0.1",
|
|
49
|
+
"@morpho-org/test": "^2.11.0",
|
|
50
50
|
"fast-check": "^4.9.0",
|
|
51
51
|
"typescript": "7.0.2",
|
|
52
52
|
"viem": "^2.55.10",
|