@morpho-dev/router 0.10.0 → 0.11.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/dist/cli.js +4698 -3654
- package/dist/drizzle/migrations/0031_sell-takeable-reindex.sql +254 -0
- package/dist/drizzle/migrations/0032_callback-type.sql +3 -0
- package/dist/drizzle/migrations/0033_obligation-id-bytes20.sql +255 -0
- package/dist/drizzle/migrations/meta/0031_snapshot.json +1652 -0
- package/dist/drizzle/migrations/meta/0033_snapshot.json +1658 -0
- package/dist/drizzle/migrations/meta/_journal.json +21 -0
- package/dist/evm/bytecode/morpho.txt +1 -1
- package/dist/index.browser.d.mts +315 -129
- package/dist/index.browser.d.mts.map +1 -1
- package/dist/index.browser.mjs +1005 -401
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.mts +378 -175
- package/dist/index.node.d.mts.map +1 -1
- package/dist/index.node.mjs +2003 -969
- package/dist/index.node.mjs.map +1 -1
- package/dist/register-otel-hook.js +7 -0
- package/package.json +31 -27
- package/dist/index.browser.d.ts +0 -5007
- package/dist/index.browser.d.ts.map +0 -1
- package/dist/index.browser.js +0 -5825
- package/dist/index.browser.js.map +0 -1
- package/dist/index.node.d.ts +0 -8263
- package/dist/index.node.d.ts.map +0 -1
- package/dist/index.node.js +0 -12566
- package/dist/index.node.js.map +0 -1
package/dist/index.browser.mjs
CHANGED
|
@@ -6,53 +6,14 @@ import { ApiBody, ApiOperation, ApiParam, ApiProperty, ApiQuery, ApiResponse, Ap
|
|
|
6
6
|
import * as z$1 from "zod";
|
|
7
7
|
import createOpenApiFetchClient from "openapi-fetch";
|
|
8
8
|
import { bytesToHex, concatHex, decodeAbiParameters, encodeAbiParameters, getAddress, hashTypedData, hexToBytes, isAddress, isHex, keccak256, maxUint256, numberToHex, pad, parseAbi, publicActions, recoverAddress, zeroAddress } from "viem";
|
|
9
|
-
import {
|
|
9
|
+
import { getBlockNumber, getLogs, multicall } from "viem/actions";
|
|
10
10
|
import { anvil, base, mainnet } from "viem/chains";
|
|
11
11
|
import { StandardMerkleTree } from "@openzeppelin/merkle-tree";
|
|
12
12
|
import { gzip, ungzip } from "pako";
|
|
13
|
+
import { context, propagation } from "@opentelemetry/api";
|
|
14
|
+
import "drizzle-orm";
|
|
15
|
+
import { bigint, boolean, foreignKey, index, integer, numeric, pgSchema, primaryKey, serial, text, timestamp, uniqueIndex, varchar } from "drizzle-orm/pg-core";
|
|
13
16
|
|
|
14
|
-
//#region \0@oxc-project+runtime@0.110.0/helpers/typeof.js
|
|
15
|
-
function _typeof(o) {
|
|
16
|
-
"@babel/helpers - typeof";
|
|
17
|
-
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
|
|
18
|
-
return typeof o;
|
|
19
|
-
} : function(o) {
|
|
20
|
-
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
21
|
-
}, _typeof(o);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
//#endregion
|
|
25
|
-
//#region \0@oxc-project+runtime@0.110.0/helpers/toPrimitive.js
|
|
26
|
-
function toPrimitive(t, r) {
|
|
27
|
-
if ("object" != _typeof(t) || !t) return t;
|
|
28
|
-
var e = t[Symbol.toPrimitive];
|
|
29
|
-
if (void 0 !== e) {
|
|
30
|
-
var i = e.call(t, r || "default");
|
|
31
|
-
if ("object" != _typeof(i)) return i;
|
|
32
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
33
|
-
}
|
|
34
|
-
return ("string" === r ? String : Number)(t);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
//#endregion
|
|
38
|
-
//#region \0@oxc-project+runtime@0.110.0/helpers/toPropertyKey.js
|
|
39
|
-
function toPropertyKey(t) {
|
|
40
|
-
var i = toPrimitive(t, "string");
|
|
41
|
-
return "symbol" == _typeof(i) ? i : i + "";
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
//#endregion
|
|
45
|
-
//#region \0@oxc-project+runtime@0.110.0/helpers/defineProperty.js
|
|
46
|
-
function _defineProperty(e, r, t) {
|
|
47
|
-
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
48
|
-
value: t,
|
|
49
|
-
enumerable: !0,
|
|
50
|
-
configurable: !0,
|
|
51
|
-
writable: !0
|
|
52
|
-
}) : e[r] = t, e;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
//#endregion
|
|
56
17
|
//#region src/utils/Errors.ts
|
|
57
18
|
var Errors_exports = /* @__PURE__ */ __exportAll({
|
|
58
19
|
BaseError: () => BaseError,
|
|
@@ -68,6 +29,10 @@ var Errors_exports = /* @__PURE__ */ __exportAll({
|
|
|
68
29
|
* ```
|
|
69
30
|
*/
|
|
70
31
|
var BaseError = class BaseError extends Error {
|
|
32
|
+
details;
|
|
33
|
+
shortMessage;
|
|
34
|
+
cause;
|
|
35
|
+
name = "BaseError";
|
|
71
36
|
constructor(shortMessage, options = {}) {
|
|
72
37
|
const details = (() => {
|
|
73
38
|
if (options.cause instanceof BaseError) {
|
|
@@ -84,10 +49,6 @@ var BaseError = class BaseError extends Error {
|
|
|
84
49
|
...details ? ["", details ? `Details: ${details}` : void 0] : []
|
|
85
50
|
].filter((x) => typeof x === "string").join("\n");
|
|
86
51
|
super(message, options.cause ? { cause: options.cause } : void 0);
|
|
87
|
-
_defineProperty(this, "details", void 0);
|
|
88
|
-
_defineProperty(this, "shortMessage", void 0);
|
|
89
|
-
_defineProperty(this, "cause", void 0);
|
|
90
|
-
_defineProperty(this, "name", "BaseError");
|
|
91
52
|
this.cause = options.cause;
|
|
92
53
|
this.details = details;
|
|
93
54
|
this.shortMessage = shortMessage;
|
|
@@ -103,9 +64,9 @@ function walk(err, fn) {
|
|
|
103
64
|
return fn ? null : err;
|
|
104
65
|
}
|
|
105
66
|
var ReorgError = class extends BaseError {
|
|
67
|
+
name = "ReorgError";
|
|
106
68
|
constructor(blockNumber) {
|
|
107
69
|
super(`Reorg detected at block number ${blockNumber}`);
|
|
108
|
-
_defineProperty(this, "name", "ReorgError");
|
|
109
70
|
}
|
|
110
71
|
};
|
|
111
72
|
|
|
@@ -176,15 +137,15 @@ function assertPrice(price) {
|
|
|
176
137
|
if (price < 0n || price > MAX_PRICE) throw new InvalidPriceError(price);
|
|
177
138
|
}
|
|
178
139
|
var InvalidTickError = class extends BaseError {
|
|
140
|
+
name = "Tick.InvalidTickError";
|
|
179
141
|
constructor(tick) {
|
|
180
142
|
super(`Invalid tick: ${tick}. Tick must be an integer between 0 and ${TICK_RANGE}.`);
|
|
181
|
-
_defineProperty(this, "name", "Tick.InvalidTickError");
|
|
182
143
|
}
|
|
183
144
|
};
|
|
184
145
|
var InvalidPriceError = class extends BaseError {
|
|
146
|
+
name = "Tick.InvalidPriceError";
|
|
185
147
|
constructor(price) {
|
|
186
148
|
super(`Invalid price: ${price}. Price must be between 0 and ${MAX_PRICE}.`);
|
|
187
|
-
_defineProperty(this, "name", "Tick.InvalidPriceError");
|
|
188
149
|
}
|
|
189
150
|
};
|
|
190
151
|
|
|
@@ -385,7 +346,7 @@ const offerExample = {
|
|
|
385
346
|
receiver_if_maker_is_seller: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401"
|
|
386
347
|
},
|
|
387
348
|
offer_hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
|
|
388
|
-
obligation_id: "
|
|
349
|
+
obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf79",
|
|
389
350
|
chain_id: 1,
|
|
390
351
|
consumed: "0",
|
|
391
352
|
takeable: "369216000000000000000000",
|
|
@@ -957,7 +918,7 @@ const positionExample = {
|
|
|
957
918
|
chain_id: 1,
|
|
958
919
|
contract: "0xC9A9C45C0eB717f8b5F193Af6bAa05A1c0Ac5078",
|
|
959
920
|
user: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
960
|
-
obligation_id: "
|
|
921
|
+
obligation_id: "0x12590ae1aee324a005be565f3bcdd16dbf8daf79",
|
|
961
922
|
reserved: "200000000000000000000",
|
|
962
923
|
block_number: 21345678
|
|
963
924
|
};
|
|
@@ -1642,11 +1603,14 @@ function isValidBase64urlJson(val) {
|
|
|
1642
1603
|
function isValidOfferHashCursor(val) {
|
|
1643
1604
|
return /^0x[a-f0-9]{64}$/i.test(val);
|
|
1644
1605
|
}
|
|
1606
|
+
function isValidObligationIdCursor(val) {
|
|
1607
|
+
return /^0x[a-f0-9]{40}$/i.test(val);
|
|
1608
|
+
}
|
|
1645
1609
|
function isValidOfferCursor(val) {
|
|
1646
1610
|
const [hash, obligationId, ...rest] = val.split(":");
|
|
1647
1611
|
if (rest.length !== 0) return false;
|
|
1648
1612
|
if (!hash || !obligationId) return false;
|
|
1649
|
-
return isValidOfferHashCursor(hash) &&
|
|
1613
|
+
return isValidOfferHashCursor(hash) && isValidObligationIdCursor(obligationId);
|
|
1650
1614
|
}
|
|
1651
1615
|
const csvArray = (schema) => z$1.preprocess((value) => {
|
|
1652
1616
|
if (value === void 0) return void 0;
|
|
@@ -1675,10 +1639,14 @@ const ConfigRuleTypes = z$1.enum([
|
|
|
1675
1639
|
"callback",
|
|
1676
1640
|
"loan_token",
|
|
1677
1641
|
"collateral_token",
|
|
1678
|
-
"oracle"
|
|
1642
|
+
"oracle",
|
|
1643
|
+
"group_consistency",
|
|
1644
|
+
"group_immutability",
|
|
1645
|
+
"max_collaterals",
|
|
1646
|
+
"min_duration"
|
|
1679
1647
|
]);
|
|
1680
1648
|
const GetConfigRulesQueryParams = z$1.object({
|
|
1681
|
-
cursor: z$1.string().regex(/^(maturity|callback|loan_token|collateral_token|oracle):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
|
|
1649
|
+
cursor: z$1.string().regex(/^(maturity|callback|loan_token|collateral_token|oracle|group_consistency|group_immutability|max_collaterals|min_duration):[1-9]\d*:.+$/, { message: "Cursor must be in the format type:chain_id:<value>" }).optional().meta({
|
|
1682
1650
|
description: "Pagination cursor in type:chain_id:<value> format",
|
|
1683
1651
|
example: "maturity:1:1730415600:end_of_next_month"
|
|
1684
1652
|
}),
|
|
@@ -1718,9 +1686,9 @@ const GetOffersQueryParams = PaginationQueryParams.omit({ cursor: true }).extend
|
|
|
1718
1686
|
description: "Side of the offer. Required when using obligation_id.",
|
|
1719
1687
|
example: "buy"
|
|
1720
1688
|
}),
|
|
1721
|
-
obligation_id: z$1.string().regex(/^0x[a-fA-F0-9]{
|
|
1689
|
+
obligation_id: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Obligation id must be a valid 20-byte hex string" }).transform((val) => val.toLowerCase()).optional().meta({
|
|
1722
1690
|
description: "Offers obligation id. Required when not using maker.",
|
|
1723
|
-
example: "
|
|
1691
|
+
example: "0x1234567890123456789012345678901234567890"
|
|
1724
1692
|
}),
|
|
1725
1693
|
maker: z$1.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Maker must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).optional().meta({
|
|
1726
1694
|
description: "Maker address to filter offers by. Alternative to obligation_id + side.",
|
|
@@ -1805,9 +1773,9 @@ const GetObligationsQueryParams = z$1.object({
|
|
|
1805
1773
|
example: "-ask,bid,maturity"
|
|
1806
1774
|
})
|
|
1807
1775
|
});
|
|
1808
|
-
const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obligation id is required and must be a valid
|
|
1776
|
+
const GetObligationParams = z$1.object({ obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 20-byte hex string" }).regex(/^0x[a-fA-F0-9]{40}$/, { error: "Obligation id must be a valid 20-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
1809
1777
|
description: "Obligation id",
|
|
1810
|
-
example: "
|
|
1778
|
+
example: "0x1234567890123456789012345678901234567890"
|
|
1811
1779
|
}) });
|
|
1812
1780
|
/** Validate a book cursor format: {side, lastTick, offersCursor} */
|
|
1813
1781
|
function isValidBookCursor(cursorString) {
|
|
@@ -1842,9 +1810,9 @@ const HealthQueryParams = z$1.object({ strict: z$1.enum([
|
|
|
1842
1810
|
}) });
|
|
1843
1811
|
const GetBookParams = z$1.object({
|
|
1844
1812
|
...BookPaginationQueryParams.shape,
|
|
1845
|
-
obligation_id: z$1.string({ error: "Obligation id is required and must be a valid
|
|
1813
|
+
obligation_id: z$1.string({ error: "Obligation id is required and must be a valid 20-byte hex string" }).regex(/^0x[a-fA-F0-9]{40}$/, { error: "Obligation id must be a valid 20-byte hex string" }).transform((val) => val.toLowerCase()).meta({
|
|
1846
1814
|
description: "Obligation id",
|
|
1847
|
-
example: "
|
|
1815
|
+
example: "0x1234567890123456789012345678901234567890"
|
|
1848
1816
|
}),
|
|
1849
1817
|
side: z$1.enum(["buy", "sell"]).meta({
|
|
1850
1818
|
description: "Side of the book (buy or sell).",
|
|
@@ -1932,55 +1900,57 @@ const MetaMorphoFactory = parseAbi(["event CreateMetaMorpho(address indexed meta
|
|
|
1932
1900
|
//#region src/core/Abi/MorphoV2.ts
|
|
1933
1901
|
const MorphoV2 = parseAbi([
|
|
1934
1902
|
"constructor()",
|
|
1935
|
-
"function collateralOf(
|
|
1903
|
+
"function collateralOf(bytes20 id, address user, uint256 collateralIndex) view returns (uint128)",
|
|
1936
1904
|
"function consume(bytes32 group, uint256 amount)",
|
|
1937
1905
|
"function consumed(address user, bytes32 group) view returns (uint256)",
|
|
1938
|
-
"function debtOf(
|
|
1906
|
+
"function debtOf(bytes20 id, address user) view returns (uint256)",
|
|
1939
1907
|
"function defaultFees(address loanToken, uint256 index) view returns (uint16)",
|
|
1940
1908
|
"function feeSetter() view returns (address)",
|
|
1941
|
-
"function fees(
|
|
1909
|
+
"function fees(bytes20 id) view returns (uint16[6])",
|
|
1942
1910
|
"function flashLoan(address token, uint256 assets, address callback, bytes data)",
|
|
1943
|
-
"function isHealthy((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation,
|
|
1944
|
-
"function liquidate((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation,
|
|
1911
|
+
"function isHealthy((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, bytes20 id, address borrower) view returns (bool)",
|
|
1912
|
+
"function liquidate((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 collateralIndex, uint256 seizedAssets, uint256 repaidUnits, address borrower, bytes data) returns (uint256, uint256)",
|
|
1945
1913
|
"function multicall(bytes[] calls)",
|
|
1946
|
-
"function obligationCreated(
|
|
1947
|
-
"function obligationState(
|
|
1914
|
+
"function obligationCreated(bytes20 id) view returns (bool)",
|
|
1915
|
+
"function obligationState(bytes20 id) view returns (uint128 totalUnits, uint128 totalShares, uint256 withdrawable, bool created, uint16[6] fees)",
|
|
1948
1916
|
"function owner() view returns (address)",
|
|
1949
|
-
"function repay((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, address onBehalf)",
|
|
1917
|
+
"function repay((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 obligationUnits, address onBehalf)",
|
|
1950
1918
|
"function session(address user) view returns (bytes32)",
|
|
1951
1919
|
"function setDefaultTradingFee(address loanToken, uint256 index, uint256 newTradingFee)",
|
|
1952
1920
|
"function setFeeSetter(address newFeeSetter)",
|
|
1953
|
-
"function setObligationTradingFee(
|
|
1921
|
+
"function setObligationTradingFee(bytes20 id, uint256 index, uint256 newTradingFee)",
|
|
1954
1922
|
"function setOwner(address newOwner)",
|
|
1955
1923
|
"function setTradingFeeRecipient(address feeRecipient)",
|
|
1956
|
-
"function sharesOf(
|
|
1924
|
+
"function sharesOf(bytes20 id, address user) view returns (uint256)",
|
|
1957
1925
|
"function shuffleSession()",
|
|
1958
|
-
"function supplyCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation,
|
|
1959
|
-
"function take(uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, address taker, address takerCallback, bytes takerCallbackData, address receiverIfTakerIsSeller, ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bool buy, address maker, uint256 assets, uint256 obligationUnits, uint256 obligationShares, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData, address receiverIfMakerIsSeller) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof) returns (uint256, uint256, uint256, uint256)",
|
|
1960
|
-
"function
|
|
1961
|
-
"function
|
|
1962
|
-
"function
|
|
1963
|
-
"function
|
|
1926
|
+
"function supplyCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 collateralIndex, uint256 assets, address onBehalf)",
|
|
1927
|
+
"function take(uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, address taker, address takerCallback, bytes takerCallbackData, address receiverIfTakerIsSeller, ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, bool buy, address maker, uint256 assets, uint256 obligationUnits, uint256 obligationShares, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData, address receiverIfMakerIsSeller) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof) returns (uint256, uint256, uint256, uint256)",
|
|
1928
|
+
"function toId((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation) view returns (bytes20)",
|
|
1929
|
+
"function toObligation(bytes20 id) view returns ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue))",
|
|
1930
|
+
"function totalShares(bytes20 id) view returns (uint256)",
|
|
1931
|
+
"function totalUnits(bytes20 id) view returns (uint256)",
|
|
1932
|
+
"function touchObligation((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation) returns (bytes20)",
|
|
1933
|
+
"function tradingFee(bytes20 id, uint256 timeToMaturity) view returns (uint256)",
|
|
1964
1934
|
"function tradingFeeRecipient() view returns (address)",
|
|
1965
|
-
"function withdraw((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, uint256 shares, address onBehalf, address receiver) returns (uint256, uint256)",
|
|
1966
|
-
"function withdrawCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation,
|
|
1967
|
-
"function withdrawable(
|
|
1935
|
+
"function withdraw((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 obligationUnits, uint256 shares, address onBehalf, address receiver) returns (uint256, uint256)",
|
|
1936
|
+
"function withdrawCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation, uint256 collateralIndex, uint256 assets, address onBehalf, address receiver)",
|
|
1937
|
+
"function withdrawable(bytes20 id) view returns (uint256)",
|
|
1968
1938
|
"event Constructor(address indexed owner)",
|
|
1969
1939
|
"event Consume(address indexed user, bytes32 indexed group, uint256 amount)",
|
|
1970
1940
|
"event FlashLoan(address indexed caller, address indexed token, uint256 assets)",
|
|
1971
|
-
"event Liquidate(address indexed caller,
|
|
1972
|
-
"event ObligationCreated(
|
|
1973
|
-
"event Repay(address indexed caller,
|
|
1941
|
+
"event Liquidate(address indexed caller, bytes20 indexed id_, uint256 collateralIndex, uint256 seizedAssets, uint256 repaidUnits, address indexed borrower, uint256 badDebt)",
|
|
1942
|
+
"event ObligationCreated(bytes20 indexed id_, (address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity, uint256 minCollatValue) obligation)",
|
|
1943
|
+
"event Repay(address indexed caller, bytes20 indexed id_, uint256 obligationUnits, address indexed onBehalf)",
|
|
1974
1944
|
"event SetDefaultTradingFee(address indexed loanToken, uint256 indexed index, uint256 newTradingFee)",
|
|
1975
1945
|
"event SetFeeSetter(address indexed feeSetter)",
|
|
1976
|
-
"event SetObligationTradingFee(
|
|
1946
|
+
"event SetObligationTradingFee(bytes20 indexed id_, uint256 indexed index, uint256 newTradingFee)",
|
|
1977
1947
|
"event SetOwner(address indexed owner)",
|
|
1978
1948
|
"event SetTradingFeeRecipient(address indexed feeRecipient)",
|
|
1979
1949
|
"event ShuffleSession(address indexed user, bytes32 session)",
|
|
1980
|
-
"event SupplyCollateral(address caller,
|
|
1981
|
-
"event Take(address caller,
|
|
1982
|
-
"event Withdraw(address caller,
|
|
1983
|
-
"event WithdrawCollateral(address caller,
|
|
1950
|
+
"event SupplyCollateral(address caller, bytes20 indexed id_, address indexed collateral, uint256 assets, address indexed onBehalf)",
|
|
1951
|
+
"event Take(address caller, bytes20 indexed id_, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, bool buyerIsLender, bool sellerIsBorrower, address sellerReceiver, bytes32 group, uint256 consumed)",
|
|
1952
|
+
"event Withdraw(address caller, bytes20 indexed id_, uint256 obligationUnits, uint256 shares, address indexed onBehalf, address indexed receiver)",
|
|
1953
|
+
"event WithdrawCollateral(address caller, bytes20 indexed id_, address indexed collateral, uint256 assets, address indexed onBehalf, address receiver)"
|
|
1984
1954
|
]);
|
|
1985
1955
|
|
|
1986
1956
|
//#endregion
|
|
@@ -2138,6 +2108,7 @@ const Morpho = [
|
|
|
2138
2108
|
//#endregion
|
|
2139
2109
|
//#region src/core/Callback.ts
|
|
2140
2110
|
var Callback_exports = /* @__PURE__ */ __exportAll({
|
|
2111
|
+
CallbackType: () => CallbackType,
|
|
2141
2112
|
Type: () => Type$1,
|
|
2142
2113
|
isEmptyCallback: () => isEmptyCallback
|
|
2143
2114
|
});
|
|
@@ -2146,30 +2117,12 @@ let Type$1 = /* @__PURE__ */ function(Type) {
|
|
|
2146
2117
|
Type["SellWithEmptyCallback"] = "sell_with_empty_callback";
|
|
2147
2118
|
return Type;
|
|
2148
2119
|
}({});
|
|
2120
|
+
let CallbackType = /* @__PURE__ */ function(CallbackType) {
|
|
2121
|
+
CallbackType["Empty"] = "empty";
|
|
2122
|
+
return CallbackType;
|
|
2123
|
+
}({});
|
|
2149
2124
|
const isEmptyCallback = (offer) => offer.callback.data === "0x";
|
|
2150
2125
|
|
|
2151
|
-
//#endregion
|
|
2152
|
-
//#region src/utils/BigMath.ts
|
|
2153
|
-
function max$1(a, b) {
|
|
2154
|
-
return a > b ? a : b;
|
|
2155
|
-
}
|
|
2156
|
-
function min(a, b) {
|
|
2157
|
-
return a < b ? a : b;
|
|
2158
|
-
}
|
|
2159
|
-
/**
|
|
2160
|
-
* Checks if at most one of the given values is non-zero.
|
|
2161
|
-
* @param values - The bigint values to check.
|
|
2162
|
-
* @returns True if zero or one value is non-zero, false if two or more are non-zero.
|
|
2163
|
-
*/
|
|
2164
|
-
function atMostOneNonZero(...values) {
|
|
2165
|
-
let nonZeroCount = 0;
|
|
2166
|
-
for (const value of values) if (value !== 0n) {
|
|
2167
|
-
nonZeroCount++;
|
|
2168
|
-
if (nonZeroCount > 1) return false;
|
|
2169
|
-
}
|
|
2170
|
-
return true;
|
|
2171
|
-
}
|
|
2172
|
-
|
|
2173
2126
|
//#endregion
|
|
2174
2127
|
//#region src/utils/batch.ts
|
|
2175
2128
|
/**
|
|
@@ -2193,6 +2146,28 @@ function* batch$1(array, batchSize) {
|
|
|
2193
2146
|
for (let i = 0; i < array.length; i += batchSize) yield array.slice(i, i + batchSize);
|
|
2194
2147
|
}
|
|
2195
2148
|
|
|
2149
|
+
//#endregion
|
|
2150
|
+
//#region src/utils/BigMath.ts
|
|
2151
|
+
function max$1(a, b) {
|
|
2152
|
+
return a > b ? a : b;
|
|
2153
|
+
}
|
|
2154
|
+
function min(a, b) {
|
|
2155
|
+
return a < b ? a : b;
|
|
2156
|
+
}
|
|
2157
|
+
/**
|
|
2158
|
+
* Checks if at most one of the given values is non-zero.
|
|
2159
|
+
* @param values - The bigint values to check.
|
|
2160
|
+
* @returns True if zero or one value is non-zero, false if two or more are non-zero.
|
|
2161
|
+
*/
|
|
2162
|
+
function atMostOneNonZero(...values) {
|
|
2163
|
+
let nonZeroCount = 0;
|
|
2164
|
+
for (const value of values) if (value !== 0n) {
|
|
2165
|
+
nonZeroCount++;
|
|
2166
|
+
if (nonZeroCount > 1) return false;
|
|
2167
|
+
}
|
|
2168
|
+
return true;
|
|
2169
|
+
}
|
|
2170
|
+
|
|
2196
2171
|
//#endregion
|
|
2197
2172
|
//#region src/core/Chain.ts
|
|
2198
2173
|
var Chain_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -2201,9 +2176,10 @@ var Chain_exports = /* @__PURE__ */ __exportAll({
|
|
|
2201
2176
|
InvalidBlockRangeError: () => InvalidBlockRangeError,
|
|
2202
2177
|
InvalidBlockWindowError: () => InvalidBlockWindowError,
|
|
2203
2178
|
MissingBlockNumberError: () => MissingBlockNumberError,
|
|
2179
|
+
UnrecoverableLogsResponseSizeError: () => UnrecoverableLogsResponseSizeError,
|
|
2204
2180
|
chainIds: () => chainIds,
|
|
2205
2181
|
chainNames: () => chainNames,
|
|
2206
|
-
chains: () => chains,
|
|
2182
|
+
chains: () => chains$1,
|
|
2207
2183
|
getChain: () => getChain,
|
|
2208
2184
|
getWhitelistedChains: () => getWhitelistedChains,
|
|
2209
2185
|
streamLogs: () => streamLogs
|
|
@@ -2220,17 +2196,17 @@ const chainNameLookup = new Map(Object.entries(ChainId).map(([key, value]) => [v
|
|
|
2220
2196
|
function getChain(chainId) {
|
|
2221
2197
|
const chainName = chainNameLookup.get(chainId);
|
|
2222
2198
|
if (!chainName) return void 0;
|
|
2223
|
-
return chains[chainName];
|
|
2199
|
+
return chains$1[chainName];
|
|
2224
2200
|
}
|
|
2225
2201
|
const getWhitelistedChains = () => {
|
|
2226
2202
|
return [
|
|
2227
|
-
chains.ethereum,
|
|
2228
|
-
chains.base,
|
|
2229
|
-
chains["ethereum-virtual-testnet"],
|
|
2230
|
-
chains.anvil
|
|
2203
|
+
chains$1.ethereum,
|
|
2204
|
+
chains$1.base,
|
|
2205
|
+
chains$1["ethereum-virtual-testnet"],
|
|
2206
|
+
chains$1.anvil
|
|
2231
2207
|
];
|
|
2232
2208
|
};
|
|
2233
|
-
const chains = {
|
|
2209
|
+
const chains$1 = {
|
|
2234
2210
|
ethereum: {
|
|
2235
2211
|
...mainnet,
|
|
2236
2212
|
id: ChainId.ETHEREUM,
|
|
@@ -2267,8 +2243,8 @@ const chains = {
|
|
|
2267
2243
|
name: "base",
|
|
2268
2244
|
custom: {
|
|
2269
2245
|
morpho: {
|
|
2270
|
-
address: "
|
|
2271
|
-
blockCreated:
|
|
2246
|
+
address: "0x4C752Cdc4b13c9A6a933CbecfE050eC0BA0B45f9",
|
|
2247
|
+
blockCreated: 42365274
|
|
2272
2248
|
},
|
|
2273
2249
|
morphoBlue: {
|
|
2274
2250
|
address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
|
|
@@ -2297,8 +2273,8 @@ const chains = {
|
|
|
2297
2273
|
name: "ethereum-virtual-testnet",
|
|
2298
2274
|
custom: {
|
|
2299
2275
|
morpho: {
|
|
2300
|
-
address: "
|
|
2301
|
-
blockCreated:
|
|
2276
|
+
address: "0x9ac49a344376964291f7289663beb78e2952de44",
|
|
2277
|
+
blockCreated: 23229385
|
|
2302
2278
|
},
|
|
2303
2279
|
morphoBlue: {
|
|
2304
2280
|
address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
|
|
@@ -2356,33 +2332,72 @@ const MAX_BATCH_SIZE = 1e4;
|
|
|
2356
2332
|
const DEFAULT_BATCH_SIZE$1 = 2500;
|
|
2357
2333
|
const MAX_BLOCK_WINDOW = 1e4;
|
|
2358
2334
|
const DEFAULT_BLOCK_WINDOW = 8e3;
|
|
2335
|
+
const MIN_BLOCK_WINDOW = 0n;
|
|
2336
|
+
const oversizedLogsErrorPatterns = [
|
|
2337
|
+
"cannot create a string longer than",
|
|
2338
|
+
"response is too big",
|
|
2339
|
+
"response size exceeded",
|
|
2340
|
+
"log response size exceeded",
|
|
2341
|
+
"query returned more than",
|
|
2342
|
+
"too many results"
|
|
2343
|
+
];
|
|
2344
|
+
const getLatestBlockNumber = async (client) => {
|
|
2345
|
+
return await getBlockNumber(client, { cacheTime: 0 });
|
|
2346
|
+
};
|
|
2359
2347
|
async function* streamLogs(parameters) {
|
|
2360
2348
|
const { client, contractAddress, event, blockNumberGte, blockNumberLte, order = "desc", options: { maxBatchSize = DEFAULT_BATCH_SIZE$1, blockWindow = DEFAULT_BLOCK_WINDOW } = {} } = parameters;
|
|
2361
2349
|
if (maxBatchSize > MAX_BATCH_SIZE) throw new InvalidBatchSizeError(maxBatchSize);
|
|
2362
2350
|
if (blockWindow > MAX_BLOCK_WINDOW) throw new InvalidBlockWindowError(blockWindow);
|
|
2363
2351
|
if (order === "asc" && blockNumberGte === void 0) throw new MissingBlockNumberError();
|
|
2364
|
-
const
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2352
|
+
const ascendingLowerBound = order === "asc" ? BigInt(blockNumberGte) : void 0;
|
|
2353
|
+
const latestBlock = await getLatestBlockNumber(client);
|
|
2354
|
+
let upperBound = blockNumberLte === void 0 ? latestBlock : min(BigInt(blockNumberLte), latestBlock);
|
|
2355
|
+
const lowerBound = BigInt(blockNumberGte || 0);
|
|
2356
|
+
const configuredBlockWindow = BigInt(blockWindow);
|
|
2357
|
+
let adaptiveBlockWindow = configuredBlockWindow;
|
|
2368
2358
|
let toBlock = 0n;
|
|
2369
|
-
if (order === "asc") toBlock = min(
|
|
2370
|
-
if (order === "desc") toBlock =
|
|
2359
|
+
if (order === "asc") toBlock = min(ascendingLowerBound + adaptiveBlockWindow, upperBound);
|
|
2360
|
+
if (order === "desc") toBlock = upperBound;
|
|
2371
2361
|
let fromBlock = 0n;
|
|
2372
|
-
if (order === "asc") fromBlock =
|
|
2373
|
-
if (order === "desc") fromBlock = max$1(BigInt(blockNumberGte || toBlock -
|
|
2374
|
-
if (order === "asc") toBlock = min(toBlock, fromBlock +
|
|
2375
|
-
if (order === "desc") fromBlock = max$1(fromBlock, toBlock -
|
|
2362
|
+
if (order === "asc") fromBlock = ascendingLowerBound;
|
|
2363
|
+
if (order === "desc") fromBlock = max$1(BigInt(blockNumberGte || toBlock - adaptiveBlockWindow), 0n);
|
|
2364
|
+
if (order === "asc") toBlock = min(toBlock, fromBlock + adaptiveBlockWindow);
|
|
2365
|
+
if (order === "desc") fromBlock = max$1(fromBlock, toBlock - adaptiveBlockWindow);
|
|
2376
2366
|
if (fromBlock > toBlock) throw new InvalidBlockRangeError(fromBlock, toBlock);
|
|
2377
2367
|
let streaming = true;
|
|
2378
2368
|
while (streaming) {
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2369
|
+
let logs;
|
|
2370
|
+
try {
|
|
2371
|
+
logs = await getLogs(client, {
|
|
2372
|
+
address: contractAddress,
|
|
2373
|
+
event,
|
|
2374
|
+
fromBlock,
|
|
2375
|
+
toBlock
|
|
2376
|
+
});
|
|
2377
|
+
} catch (err) {
|
|
2378
|
+
if (order === "asc" && isBlockOutOfRangeError(err)) {
|
|
2379
|
+
const previousUpperBound = upperBound;
|
|
2380
|
+
const previousFromBlock = fromBlock;
|
|
2381
|
+
const previousToBlock = toBlock;
|
|
2382
|
+
const latestBlockOnRetry = await getLatestBlockNumber(client);
|
|
2383
|
+
upperBound = min(upperBound, latestBlockOnRetry);
|
|
2384
|
+
if (upperBound < ascendingLowerBound) throw new InvalidBlockRangeError(ascendingLowerBound, upperBound);
|
|
2385
|
+
toBlock = min(toBlock, upperBound);
|
|
2386
|
+
fromBlock = max$1(min(fromBlock, upperBound), ascendingLowerBound);
|
|
2387
|
+
if (fromBlock > toBlock) throw new InvalidBlockRangeError(fromBlock, toBlock);
|
|
2388
|
+
if (!(upperBound < previousUpperBound || fromBlock < previousFromBlock || toBlock < previousToBlock)) throw err;
|
|
2389
|
+
continue;
|
|
2390
|
+
}
|
|
2391
|
+
if (isOversizedLogsError(err)) {
|
|
2392
|
+
if (fromBlock === toBlock) throw new UnrecoverableLogsResponseSizeError(fromBlock, err);
|
|
2393
|
+
adaptiveBlockWindow = max$1((toBlock - fromBlock) / 2n, MIN_BLOCK_WINDOW);
|
|
2394
|
+
if (order === "asc") toBlock = min(fromBlock + adaptiveBlockWindow, upperBound);
|
|
2395
|
+
else fromBlock = max$1(toBlock - adaptiveBlockWindow, lowerBound);
|
|
2396
|
+
continue;
|
|
2397
|
+
}
|
|
2398
|
+
throw err;
|
|
2399
|
+
}
|
|
2400
|
+
streaming = order === "asc" ? toBlock < upperBound : fromBlock > lowerBound;
|
|
2386
2401
|
if (logs.length === 0 && !streaming) break;
|
|
2387
2402
|
if (logs.length === 0 && streaming) yield {
|
|
2388
2403
|
logs: [],
|
|
@@ -2397,17 +2412,19 @@ async function* streamLogs(parameters) {
|
|
|
2397
2412
|
logs: logBatch,
|
|
2398
2413
|
blockNumber: logBatch.length === maxBatchSize ? Number(logBatch[logBatch.length - 1]?.blockNumber) : order === "asc" ? Number(toBlock) : Number(fromBlock)
|
|
2399
2414
|
};
|
|
2415
|
+
if (adaptiveBlockWindow < configuredBlockWindow) {
|
|
2416
|
+
const expandedBlockWindow = adaptiveBlockWindow === 0n ? 1n : adaptiveBlockWindow * 2n;
|
|
2417
|
+
adaptiveBlockWindow = min(expandedBlockWindow, configuredBlockWindow);
|
|
2418
|
+
}
|
|
2400
2419
|
if (order === "asc") {
|
|
2401
|
-
const upperBound = BigInt(blockNumberLte || latestBlock);
|
|
2402
2420
|
const nextFromBlock = min(BigInt(toBlock) + 1n, upperBound);
|
|
2403
|
-
const nextToBlock = min(toBlock +
|
|
2421
|
+
const nextToBlock = min(toBlock + adaptiveBlockWindow + 1n, upperBound);
|
|
2404
2422
|
fromBlock = nextFromBlock;
|
|
2405
2423
|
toBlock = nextToBlock;
|
|
2406
2424
|
}
|
|
2407
2425
|
if (order === "desc") {
|
|
2408
|
-
const lowerBound = BigInt(blockNumberGte || 0);
|
|
2409
2426
|
const nextToBlock = max$1(fromBlock - 1n, lowerBound);
|
|
2410
|
-
const nextFromBlock = max$1(fromBlock -
|
|
2427
|
+
const nextFromBlock = max$1(fromBlock - adaptiveBlockWindow - 1n, lowerBound);
|
|
2411
2428
|
toBlock = nextToBlock;
|
|
2412
2429
|
fromBlock = nextFromBlock;
|
|
2413
2430
|
}
|
|
@@ -2417,30 +2434,62 @@ async function* streamLogs(parameters) {
|
|
|
2417
2434
|
blockNumber: order === "asc" ? Number(toBlock) : Number(fromBlock)
|
|
2418
2435
|
};
|
|
2419
2436
|
}
|
|
2437
|
+
const isBlockOutOfRangeError = (error) => {
|
|
2438
|
+
let cause = error;
|
|
2439
|
+
while (cause && typeof cause === "object") {
|
|
2440
|
+
const candidate = cause;
|
|
2441
|
+
if (typeof candidate.message === "string" && candidate.message.includes("BlockOutOfRangeError") || typeof candidate.details === "string" && candidate.details.includes("BlockOutOfRangeError")) return true;
|
|
2442
|
+
cause = candidate.cause;
|
|
2443
|
+
}
|
|
2444
|
+
return false;
|
|
2445
|
+
};
|
|
2420
2446
|
var InvalidBlockRangeError = class extends BaseError {
|
|
2447
|
+
name = "Chain.InvalidBlockRangeError";
|
|
2448
|
+
fromBlock;
|
|
2449
|
+
toBlock;
|
|
2421
2450
|
constructor(fromBlock, toBlock) {
|
|
2422
2451
|
super(`Invalid block range while streaming data from chain. From block ${fromBlock} to block ${toBlock}.`);
|
|
2423
|
-
|
|
2452
|
+
this.fromBlock = fromBlock;
|
|
2453
|
+
this.toBlock = toBlock;
|
|
2424
2454
|
}
|
|
2425
2455
|
};
|
|
2426
2456
|
var InvalidBlockWindowError = class extends BaseError {
|
|
2457
|
+
name = "Chain.InvalidBlockWindowError";
|
|
2427
2458
|
constructor(blockWindow) {
|
|
2428
2459
|
super(`Invalid block window while streaming data from chain. Maximum is ${MAX_BLOCK_WINDOW}. Got ${blockWindow}.`);
|
|
2429
|
-
_defineProperty(this, "name", "Chain.InvalidBlockWindowError");
|
|
2430
2460
|
}
|
|
2431
2461
|
};
|
|
2432
2462
|
var InvalidBatchSizeError = class extends BaseError {
|
|
2463
|
+
name = "Chain.InvalidBatchSizeError";
|
|
2433
2464
|
constructor(maxBatchSize) {
|
|
2434
2465
|
super(`Invalid batch size while streaming data from chain. Maximum is ${MAX_BATCH_SIZE}. Got ${maxBatchSize}.`);
|
|
2435
|
-
_defineProperty(this, "name", "Chain.InvalidBatchSizeError");
|
|
2436
2466
|
}
|
|
2437
2467
|
};
|
|
2438
2468
|
var MissingBlockNumberError = class extends BaseError {
|
|
2469
|
+
name = "Chain.MissingBlockNumberError";
|
|
2439
2470
|
constructor() {
|
|
2440
2471
|
super("Missing block number when streaming data from chain in ascending order.");
|
|
2441
|
-
_defineProperty(this, "name", "Chain.MissingBlockNumberError");
|
|
2442
2472
|
}
|
|
2443
2473
|
};
|
|
2474
|
+
var UnrecoverableLogsResponseSizeError = class extends BaseError {
|
|
2475
|
+
name = "Chain.UnrecoverableLogsResponseSizeError";
|
|
2476
|
+
constructor(blockNumber, cause) {
|
|
2477
|
+
const rootCause = cause instanceof Error ? cause : cause === void 0 ? void 0 : new Error(String(cause));
|
|
2478
|
+
super(`Failed to stream logs because even a single-block query exceeded the RPC response size limit at block ${blockNumber}.`, { cause: rootCause });
|
|
2479
|
+
}
|
|
2480
|
+
};
|
|
2481
|
+
function isOversizedLogsError(err) {
|
|
2482
|
+
return oversizedLogsErrorPatterns.some((pattern) => collectErrorMessages(err).includes(pattern));
|
|
2483
|
+
}
|
|
2484
|
+
function collectErrorMessages(err) {
|
|
2485
|
+
if (!(err instanceof Error)) return "";
|
|
2486
|
+
const fragments = [err.message];
|
|
2487
|
+
const candidate = err;
|
|
2488
|
+
if (typeof candidate.details === "string") fragments.push(candidate.details);
|
|
2489
|
+
if (typeof candidate.shortMessage === "string") fragments.push(candidate.shortMessage);
|
|
2490
|
+
if (candidate.cause instanceof Error) fragments.push(collectErrorMessages(candidate.cause));
|
|
2491
|
+
return fragments.join(" ").toLowerCase();
|
|
2492
|
+
}
|
|
2444
2493
|
|
|
2445
2494
|
//#endregion
|
|
2446
2495
|
//#region src/core/ChainRegistry.ts
|
|
@@ -2663,15 +2712,15 @@ function from$11(lltv) {
|
|
|
2663
2712
|
return BigInt(lltv * 10 ** 18);
|
|
2664
2713
|
}
|
|
2665
2714
|
var InvalidOptionError$1 = class extends BaseError {
|
|
2715
|
+
name = "LLTV.InvalidOptionError";
|
|
2666
2716
|
constructor(input) {
|
|
2667
2717
|
super(`Invalid LLTV option. Input: "${input}". Accepted values are: ${Options.map((option) => `"${option}"`).join(", ")}.`);
|
|
2668
|
-
_defineProperty(this, "name", "LLTV.InvalidOptionError");
|
|
2669
2718
|
}
|
|
2670
2719
|
};
|
|
2671
2720
|
var InvalidLLTVError = class extends BaseError {
|
|
2721
|
+
name = "LLTV.InvalidLLTVError";
|
|
2672
2722
|
constructor(input) {
|
|
2673
2723
|
super(`Invalid LLTV. Input: "${input}". Accepted values are: ${LLTV_SCALED.map((option) => `"${option}"`).join(", ")}.`);
|
|
2674
|
-
_defineProperty(this, "name", "LLTV.InvalidLLTVError");
|
|
2675
2724
|
}
|
|
2676
2725
|
};
|
|
2677
2726
|
const LLTVSchema = z$1.bigint({ coerce: true }).refine((lltv) => {
|
|
@@ -2806,9 +2855,9 @@ function convertToShares(parameters) {
|
|
|
2806
2855
|
return parameters.assets * (parameters.totalSupply + 10n ** BigInt(parameters.decimalsOffset)) / denominator;
|
|
2807
2856
|
}
|
|
2808
2857
|
var DenominatorIsZeroError = class extends BaseError {
|
|
2858
|
+
name = "ERC4626.DenominatorIsZeroError";
|
|
2809
2859
|
constructor() {
|
|
2810
2860
|
super("Denominator is 0.");
|
|
2811
|
-
_defineProperty(this, "name", "ERC4626.DenominatorIsZeroError");
|
|
2812
2861
|
}
|
|
2813
2862
|
};
|
|
2814
2863
|
|
|
@@ -2876,9 +2925,9 @@ const MaturitySchema = z$1.number().int().refine((maturity) => {
|
|
|
2876
2925
|
}
|
|
2877
2926
|
}, { error: (issue) => {
|
|
2878
2927
|
try {
|
|
2879
|
-
return `The maturity is set to ${/* @__PURE__ */ new Date(issue.input * 1e3)}. It must
|
|
2928
|
+
return `The maturity is set to ${/* @__PURE__ */ new Date(issue.input * 1e3)}. It must be at 15:00:00 UTC.`;
|
|
2880
2929
|
} catch (_) {
|
|
2881
|
-
return `The maturity is set to ${issue.input}. It must
|
|
2930
|
+
return `The maturity is set to ${issue.input}. It must be at 15:00:00 UTC.`;
|
|
2882
2931
|
}
|
|
2883
2932
|
} }).transform((maturity) => maturity);
|
|
2884
2933
|
let MaturityType = /* @__PURE__ */ function(MaturityType) {
|
|
@@ -2910,9 +2959,14 @@ function from$9(ts) {
|
|
|
2910
2959
|
throw new InvalidOptionError(ts);
|
|
2911
2960
|
}
|
|
2912
2961
|
if (typeof ts === "number" && ts > 0xe8d4a51000) throw new InvalidFormatError();
|
|
2913
|
-
if (!
|
|
2962
|
+
if (!isAt15UTC(ts)) throw new InvalidDateError(ts);
|
|
2914
2963
|
return ts;
|
|
2915
2964
|
}
|
|
2965
|
+
/** Checks whether a timestamp (in seconds) falls at exactly 15:00:00 UTC. */
|
|
2966
|
+
function isAt15UTC(ts) {
|
|
2967
|
+
const date = /* @__PURE__ */ new Date(ts * 1e3);
|
|
2968
|
+
return date.getUTCHours() === 15 && date.getUTCMinutes() === 0 && date.getUTCSeconds() === 0 && date.getUTCMilliseconds() === 0;
|
|
2969
|
+
}
|
|
2916
2970
|
/** Returns the end of the current week (friday at 15:00:00 UTC) */
|
|
2917
2971
|
const endOfWeek = () => fridayOfWeek(0);
|
|
2918
2972
|
/** Returns the end of the next week (friday at 15:00:00 UTC) */
|
|
@@ -2965,21 +3019,21 @@ const lastFridayOfQuarter = (quartersAhead = 0) => {
|
|
|
2965
3019
|
return lastFridayOfMonth(now.getUTCFullYear() + Math.floor(quarterIndex / 4), quarterIndex % 4 * 3 + 2);
|
|
2966
3020
|
};
|
|
2967
3021
|
var InvalidFormatError = class extends BaseError {
|
|
3022
|
+
name = "Maturity.InvalidFormatError";
|
|
2968
3023
|
constructor() {
|
|
2969
3024
|
super("Invalid maturity format. Maturity should be expressed in seconds.");
|
|
2970
|
-
_defineProperty(this, "name", "Maturity.InvalidFormatError");
|
|
2971
3025
|
}
|
|
2972
3026
|
};
|
|
2973
3027
|
var InvalidDateError = class extends BaseError {
|
|
3028
|
+
name = "Maturity.InvalidDateError";
|
|
2974
3029
|
constructor(input) {
|
|
2975
|
-
super(`Invalid maturity date. Input: "${input}".
|
|
2976
|
-
_defineProperty(this, "name", "Maturity.InvalidDateError");
|
|
3030
|
+
super(`Invalid maturity date. Input: "${input}". Maturity must be at 15:00:00 UTC.`);
|
|
2977
3031
|
}
|
|
2978
3032
|
};
|
|
2979
3033
|
var InvalidOptionError = class extends BaseError {
|
|
3034
|
+
name = "Maturity.InvalidOptionError";
|
|
2980
3035
|
constructor(input) {
|
|
2981
3036
|
super(`Invalid maturity option. Input: "${input}". Accepted values are: ${Object.keys(MaturityOptions).map((option) => `"${option}"`).join(", ")}.`);
|
|
2982
|
-
_defineProperty(this, "name", "Maturity.InvalidOptionError");
|
|
2983
3037
|
}
|
|
2984
3038
|
};
|
|
2985
3039
|
|
|
@@ -3000,7 +3054,8 @@ var Obligation_exports = /* @__PURE__ */ __exportAll({
|
|
|
3000
3054
|
const ObligationSchema = z$1.object({
|
|
3001
3055
|
loanToken: z$1.string().transform(transformAddress),
|
|
3002
3056
|
collaterals: CollateralsSchema,
|
|
3003
|
-
maturity: MaturitySchema
|
|
3057
|
+
maturity: MaturitySchema,
|
|
3058
|
+
minCollatValue: z$1.bigint({ coerce: true }).min(0n).optional().default(0n)
|
|
3004
3059
|
});
|
|
3005
3060
|
const abi = [
|
|
3006
3061
|
{
|
|
@@ -3015,6 +3070,10 @@ const abi = [
|
|
|
3015
3070
|
{
|
|
3016
3071
|
type: "uint256",
|
|
3017
3072
|
name: "maturity"
|
|
3073
|
+
},
|
|
3074
|
+
{
|
|
3075
|
+
type: "uint256",
|
|
3076
|
+
name: "minCollatValue"
|
|
3018
3077
|
}
|
|
3019
3078
|
];
|
|
3020
3079
|
const tupleAbi = [{
|
|
@@ -3052,7 +3111,8 @@ function from$8(parameters) {
|
|
|
3052
3111
|
return {
|
|
3053
3112
|
loanToken: parsedObligation.loanToken.toLowerCase(),
|
|
3054
3113
|
collaterals: parsedObligation.collaterals.sort((a, b) => a.asset.localeCompare(b.asset)),
|
|
3055
|
-
maturity: parsedObligation.maturity
|
|
3114
|
+
maturity: parsedObligation.maturity,
|
|
3115
|
+
minCollatValue: parsedObligation.minCollatValue
|
|
3056
3116
|
};
|
|
3057
3117
|
} catch (error) {
|
|
3058
3118
|
throw new InvalidObligationError(error);
|
|
@@ -3069,7 +3129,8 @@ function fromSnakeCase$2(input) {
|
|
|
3069
3129
|
}
|
|
3070
3130
|
/**
|
|
3071
3131
|
* Calculates a canonical key for an obligation payload.
|
|
3072
|
-
* The key is computed as keccak256(abi.encode(loanToken, collaterals, maturity)).
|
|
3132
|
+
* The key is computed as keccak256(abi.encode(loanToken, collaterals, maturity, minCollatValue)).
|
|
3133
|
+
* If omitted, `minCollatValue` defaults to `0`.
|
|
3073
3134
|
* @throws If the collaterals are not sorted alphabetically by address. {@link CollateralsAreNotSortedError}
|
|
3074
3135
|
* @param parameters - {@link key.Parameters}
|
|
3075
3136
|
* @returns The obligation key as a 32-byte hex string. {@link key.ReturnType}
|
|
@@ -3095,7 +3156,8 @@ function key(parameters) {
|
|
|
3095
3156
|
lltv: c.lltv,
|
|
3096
3157
|
oracle: c.oracle.toLowerCase()
|
|
3097
3158
|
})),
|
|
3098
|
-
BigInt(parameters.maturity)
|
|
3159
|
+
BigInt(parameters.maturity),
|
|
3160
|
+
parameters.minCollatValue ?? 0n
|
|
3099
3161
|
]));
|
|
3100
3162
|
}
|
|
3101
3163
|
/**
|
|
@@ -3129,15 +3191,15 @@ function fromOffer$1(offer) {
|
|
|
3129
3191
|
});
|
|
3130
3192
|
}
|
|
3131
3193
|
var InvalidObligationError = class extends BaseError {
|
|
3194
|
+
name = "Obligation.InvalidObligationError";
|
|
3132
3195
|
constructor(error) {
|
|
3133
3196
|
super("Invalid obligation.", { cause: error });
|
|
3134
|
-
_defineProperty(this, "name", "Obligation.InvalidObligationError");
|
|
3135
3197
|
}
|
|
3136
3198
|
};
|
|
3137
3199
|
var CollateralsAreNotSortedError = class extends BaseError {
|
|
3200
|
+
name = "Obligation.CollateralsAreNotSortedError";
|
|
3138
3201
|
constructor() {
|
|
3139
3202
|
super("Collaterals are not sorted alphabetically by address.");
|
|
3140
|
-
_defineProperty(this, "name", "Obligation.CollateralsAreNotSortedError");
|
|
3141
3203
|
}
|
|
3142
3204
|
};
|
|
3143
3205
|
|
|
@@ -3147,39 +3209,42 @@ var Id_exports = /* @__PURE__ */ __exportAll({
|
|
|
3147
3209
|
creationCode: () => creationCode,
|
|
3148
3210
|
toId: () => toId
|
|
3149
3211
|
});
|
|
3150
|
-
const CREATION_CODE_PREFIX = "
|
|
3212
|
+
const CREATION_CODE_PREFIX = "0x600b380380600b5f395ff3";
|
|
3151
3213
|
/**
|
|
3152
3214
|
* Builds the same creation code as `IdLib.creationCode` in Solidity.
|
|
3153
3215
|
*
|
|
3154
|
-
* Layout: `prefix (11 bytes) +
|
|
3216
|
+
* Layout: `prefix (11 bytes) + abi.encode(obligation)`.
|
|
3155
3217
|
*
|
|
3156
3218
|
* @param parameters - {@link creationCode.Parameters}
|
|
3157
3219
|
* @returns The CREATE2 init code bytes. {@link creationCode.ReturnType}
|
|
3158
3220
|
*/
|
|
3159
3221
|
function creationCode(parameters) {
|
|
3160
|
-
|
|
3222
|
+
return concatHex([CREATION_CODE_PREFIX, encodeAbiParameters(tupleAbi, [{
|
|
3161
3223
|
loanToken: parameters.obligation.loanToken.toLowerCase(),
|
|
3162
3224
|
collaterals: parameters.obligation.collaterals.map((collateral) => ({
|
|
3163
3225
|
token: collateral.asset.toLowerCase(),
|
|
3164
3226
|
lltv: collateral.lltv,
|
|
3165
3227
|
oracle: collateral.oracle.toLowerCase()
|
|
3166
3228
|
})),
|
|
3167
|
-
maturity: BigInt(parameters.obligation.maturity)
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
CREATION_CODE_PREFIX,
|
|
3171
|
-
numberToHex(BigInt(parameters.chainId), { size: 32 }),
|
|
3172
|
-
parameters.morphoV2.toLowerCase(),
|
|
3173
|
-
encodedObligation
|
|
3174
|
-
]);
|
|
3229
|
+
maturity: BigInt(parameters.obligation.maturity),
|
|
3230
|
+
minCollatValue: 0n
|
|
3231
|
+
}])]);
|
|
3175
3232
|
}
|
|
3176
3233
|
/**
|
|
3177
|
-
* Computes the same id as `IdLib.toId` in Solidity
|
|
3234
|
+
* Computes the same id as `IdLib.toId` in Solidity using the CREATE2 preimage:
|
|
3235
|
+
* `keccak256(0xff ++ morphoV2 ++ chainId ++ keccak256(creationCode))`,
|
|
3236
|
+
* then truncates to the lower 20 bytes.
|
|
3237
|
+
*
|
|
3178
3238
|
* @param parameters - {@link toId.Parameters}
|
|
3179
3239
|
* @returns The obligation id. {@link toId.ReturnType}
|
|
3180
3240
|
*/
|
|
3181
3241
|
function toId(parameters) {
|
|
3182
|
-
return keccak256(
|
|
3242
|
+
return `0x${keccak256(concatHex([
|
|
3243
|
+
"0xff",
|
|
3244
|
+
parameters.morphoV2.toLowerCase(),
|
|
3245
|
+
numberToHex(BigInt(parameters.chainId), { size: 32 }),
|
|
3246
|
+
keccak256(creationCode(parameters))
|
|
3247
|
+
])).slice(-40)}`;
|
|
3183
3248
|
}
|
|
3184
3249
|
|
|
3185
3250
|
//#endregion
|
|
@@ -3476,7 +3541,7 @@ function hash(offer) {
|
|
|
3476
3541
|
* The id is computed with {@link Id.toId}.
|
|
3477
3542
|
* @param offer - The offer to calculate the obligation id for.
|
|
3478
3543
|
* @param parameters - The chain context used by the onchain id function.
|
|
3479
|
-
* @returns The obligation id as a
|
|
3544
|
+
* @returns The obligation id as a 20-byte hex string.
|
|
3480
3545
|
*/
|
|
3481
3546
|
function obligationId(offer, parameters) {
|
|
3482
3547
|
return toId({
|
|
@@ -3639,10 +3704,10 @@ const takeEvent = {
|
|
|
3639
3704
|
internalType: "address"
|
|
3640
3705
|
},
|
|
3641
3706
|
{
|
|
3642
|
-
name: "
|
|
3643
|
-
type: "
|
|
3707
|
+
name: "id_",
|
|
3708
|
+
type: "bytes20",
|
|
3644
3709
|
indexed: true,
|
|
3645
|
-
internalType: "
|
|
3710
|
+
internalType: "bytes20"
|
|
3646
3711
|
},
|
|
3647
3712
|
{
|
|
3648
3713
|
name: "maker",
|
|
@@ -3761,10 +3826,10 @@ const repayEvent = {
|
|
|
3761
3826
|
internalType: "address"
|
|
3762
3827
|
},
|
|
3763
3828
|
{
|
|
3764
|
-
name: "
|
|
3765
|
-
type: "
|
|
3829
|
+
name: "id_",
|
|
3830
|
+
type: "bytes20",
|
|
3766
3831
|
indexed: true,
|
|
3767
|
-
internalType: "
|
|
3832
|
+
internalType: "bytes20"
|
|
3768
3833
|
},
|
|
3769
3834
|
{
|
|
3770
3835
|
name: "obligationUnits",
|
|
@@ -3795,46 +3860,35 @@ const liquidateEvent = {
|
|
|
3795
3860
|
internalType: "address"
|
|
3796
3861
|
},
|
|
3797
3862
|
{
|
|
3798
|
-
name: "
|
|
3799
|
-
type: "
|
|
3863
|
+
name: "id_",
|
|
3864
|
+
type: "bytes20",
|
|
3800
3865
|
indexed: true,
|
|
3801
|
-
internalType: "
|
|
3866
|
+
internalType: "bytes20"
|
|
3802
3867
|
},
|
|
3803
3868
|
{
|
|
3804
|
-
name: "
|
|
3805
|
-
type: "
|
|
3869
|
+
name: "collateralIndex",
|
|
3870
|
+
type: "uint256",
|
|
3806
3871
|
indexed: false,
|
|
3807
|
-
internalType: "
|
|
3808
|
-
components: [
|
|
3809
|
-
{
|
|
3810
|
-
name: "collateralIndex",
|
|
3811
|
-
type: "uint256",
|
|
3812
|
-
internalType: "uint256"
|
|
3813
|
-
},
|
|
3814
|
-
{
|
|
3815
|
-
name: "repaid",
|
|
3816
|
-
type: "uint256",
|
|
3817
|
-
internalType: "uint256"
|
|
3818
|
-
},
|
|
3819
|
-
{
|
|
3820
|
-
name: "seized",
|
|
3821
|
-
type: "uint256",
|
|
3822
|
-
internalType: "uint256"
|
|
3823
|
-
}
|
|
3824
|
-
]
|
|
3872
|
+
internalType: "uint256"
|
|
3825
3873
|
},
|
|
3826
3874
|
{
|
|
3827
|
-
name: "
|
|
3828
|
-
type: "
|
|
3829
|
-
indexed:
|
|
3830
|
-
internalType: "
|
|
3875
|
+
name: "seizedAssets",
|
|
3876
|
+
type: "uint256",
|
|
3877
|
+
indexed: false,
|
|
3878
|
+
internalType: "uint256"
|
|
3831
3879
|
},
|
|
3832
3880
|
{
|
|
3833
|
-
name: "
|
|
3881
|
+
name: "repaidUnits",
|
|
3834
3882
|
type: "uint256",
|
|
3835
3883
|
indexed: false,
|
|
3836
3884
|
internalType: "uint256"
|
|
3837
3885
|
},
|
|
3886
|
+
{
|
|
3887
|
+
name: "borrower",
|
|
3888
|
+
type: "address",
|
|
3889
|
+
indexed: true,
|
|
3890
|
+
internalType: "address"
|
|
3891
|
+
},
|
|
3838
3892
|
{
|
|
3839
3893
|
name: "badDebt",
|
|
3840
3894
|
type: "uint256",
|
|
@@ -3858,10 +3912,10 @@ const supplyCollateralEvent = {
|
|
|
3858
3912
|
internalType: "address"
|
|
3859
3913
|
},
|
|
3860
3914
|
{
|
|
3861
|
-
name: "
|
|
3862
|
-
type: "
|
|
3915
|
+
name: "id_",
|
|
3916
|
+
type: "bytes20",
|
|
3863
3917
|
indexed: true,
|
|
3864
|
-
internalType: "
|
|
3918
|
+
internalType: "bytes20"
|
|
3865
3919
|
},
|
|
3866
3920
|
{
|
|
3867
3921
|
name: "collateral",
|
|
@@ -3898,10 +3952,10 @@ const withdrawCollateralEvent = {
|
|
|
3898
3952
|
internalType: "address"
|
|
3899
3953
|
},
|
|
3900
3954
|
{
|
|
3901
|
-
name: "
|
|
3902
|
-
type: "
|
|
3955
|
+
name: "id_",
|
|
3956
|
+
type: "bytes20",
|
|
3903
3957
|
indexed: true,
|
|
3904
|
-
internalType: "
|
|
3958
|
+
internalType: "bytes20"
|
|
3905
3959
|
},
|
|
3906
3960
|
{
|
|
3907
3961
|
name: "collateral",
|
|
@@ -3931,9 +3985,9 @@ const withdrawCollateralEvent = {
|
|
|
3931
3985
|
anonymous: false
|
|
3932
3986
|
};
|
|
3933
3987
|
var InvalidOfferError = class InvalidOfferError extends BaseError {
|
|
3988
|
+
name = "Offer.InvalidOfferError";
|
|
3934
3989
|
constructor(error) {
|
|
3935
3990
|
super("Invalid offer.", { cause: error });
|
|
3936
|
-
_defineProperty(this, "name", "Offer.InvalidOfferError");
|
|
3937
3991
|
}
|
|
3938
3992
|
/**
|
|
3939
3993
|
* Formats ZodError issues into a human-readable string with line breaks.
|
|
@@ -4146,9 +4200,9 @@ function random() {
|
|
|
4146
4200
|
});
|
|
4147
4201
|
}
|
|
4148
4202
|
var InvalidQuoteError = class extends BaseError {
|
|
4203
|
+
name = "Quote.InvalidQuoteError";
|
|
4149
4204
|
constructor(error) {
|
|
4150
4205
|
super("Invalid quote.", { cause: error });
|
|
4151
|
-
_defineProperty(this, "name", "Quote.InvalidQuoteError");
|
|
4152
4206
|
}
|
|
4153
4207
|
};
|
|
4154
4208
|
function sideFromTick(side) {
|
|
@@ -4294,16 +4348,16 @@ function getSegment(timeToMaturity) {
|
|
|
4294
4348
|
}
|
|
4295
4349
|
/** Error thrown when a fee value is invalid (negative or exceeds WAD). */
|
|
4296
4350
|
var InvalidFeeError = class extends BaseError {
|
|
4351
|
+
name = "TradingFee.InvalidFeeError";
|
|
4297
4352
|
constructor(fee, index) {
|
|
4298
4353
|
super(`Invalid fee at index ${index}: ${fee}. Fee must be between 0 and ${WAD} (WAD).`);
|
|
4299
|
-
_defineProperty(this, "name", "TradingFee.InvalidFeeError");
|
|
4300
4354
|
}
|
|
4301
4355
|
};
|
|
4302
4356
|
/** Error thrown when fees array doesn't have exactly 6 elements. */
|
|
4303
4357
|
var InvalidFeesLengthError = class extends BaseError {
|
|
4358
|
+
name = "TradingFee.InvalidFeesLengthError";
|
|
4304
4359
|
constructor(length) {
|
|
4305
4360
|
super(`Invalid fees length: ${length}. Expected exactly 6 fee values.`);
|
|
4306
|
-
_defineProperty(this, "name", "TradingFee.InvalidFeesLengthError");
|
|
4307
4361
|
}
|
|
4308
4362
|
};
|
|
4309
4363
|
|
|
@@ -4343,7 +4397,7 @@ var Tree_exports = /* @__PURE__ */ __exportAll({
|
|
|
4343
4397
|
EncodeError: () => EncodeError,
|
|
4344
4398
|
SignatureDomainError: () => SignatureDomainError,
|
|
4345
4399
|
TreeError: () => TreeError,
|
|
4346
|
-
VERSION: () => VERSION,
|
|
4400
|
+
VERSION: () => VERSION$1,
|
|
4347
4401
|
decode: () => decode,
|
|
4348
4402
|
encode: () => encode,
|
|
4349
4403
|
encodeUnsigned: () => encodeUnsigned,
|
|
@@ -4352,7 +4406,7 @@ var Tree_exports = /* @__PURE__ */ __exportAll({
|
|
|
4352
4406
|
signatureDomain: () => signatureDomain,
|
|
4353
4407
|
signatureTypes: () => signatureTypes
|
|
4354
4408
|
});
|
|
4355
|
-
const VERSION = 1;
|
|
4409
|
+
const VERSION$1 = 1;
|
|
4356
4410
|
/**
|
|
4357
4411
|
* EIP-712 types for signing the tree root (Root(bytes32 root)).
|
|
4358
4412
|
*/
|
|
@@ -4546,7 +4600,7 @@ const encodeUnsigned = (tree) => {
|
|
|
4546
4600
|
return bytesToHex(encodeUnsignedBytes(tree));
|
|
4547
4601
|
};
|
|
4548
4602
|
const validateTreeForEncoding = (tree) => {
|
|
4549
|
-
if (VERSION > 255) throw new EncodeError(`version overflow: ${VERSION} exceeds 255`);
|
|
4603
|
+
if (VERSION$1 > 255) throw new EncodeError(`version overflow: ${VERSION$1} exceeds 255`);
|
|
4550
4604
|
const computed = from$1(tree.offers);
|
|
4551
4605
|
if (tree.root !== computed.root) throw new EncodeError(`root mismatch: expected ${computed.root}, got ${tree.root}`);
|
|
4552
4606
|
};
|
|
@@ -4555,7 +4609,7 @@ const encodeUnsignedBytes = (tree) => {
|
|
|
4555
4609
|
const compressed = gzip(JSON.stringify(offersPayload));
|
|
4556
4610
|
const rootBytes = hexToBytes(tree.root);
|
|
4557
4611
|
const encoded = new Uint8Array(1 + compressed.length + 32);
|
|
4558
|
-
encoded[0] = VERSION;
|
|
4612
|
+
encoded[0] = VERSION$1;
|
|
4559
4613
|
encoded.set(compressed, 1);
|
|
4560
4614
|
encoded.set(rootBytes, 1 + compressed.length);
|
|
4561
4615
|
return encoded;
|
|
@@ -4589,7 +4643,7 @@ const decode = async (encoded, domain) => {
|
|
|
4589
4643
|
const bytes = hexToBytes(encoded);
|
|
4590
4644
|
if (bytes.length < 98) throw new DecodeError("payload too short");
|
|
4591
4645
|
const version = bytes[0];
|
|
4592
|
-
if (version !== (VERSION & 255)) throw new DecodeError(`invalid version: expected ${VERSION}, got ${version ?? 0}`);
|
|
4646
|
+
if (version !== (VERSION$1 & 255)) throw new DecodeError(`invalid version: expected ${VERSION$1}, got ${version ?? 0}`);
|
|
4593
4647
|
const signature = bytesToHex(bytes.slice(-65));
|
|
4594
4648
|
const root = bytesToHex(bytes.slice(-97, -65));
|
|
4595
4649
|
assertHex(root, 32, "root");
|
|
@@ -4626,9 +4680,9 @@ const decode = async (encoded, domain) => {
|
|
|
4626
4680
|
* Indicates structural issues with the tree (missing offers, inconsistent state).
|
|
4627
4681
|
*/
|
|
4628
4682
|
var TreeError = class extends BaseError {
|
|
4683
|
+
name = "Tree.TreeError";
|
|
4629
4684
|
constructor(reason) {
|
|
4630
4685
|
super(`Tree error: ${reason}`);
|
|
4631
|
-
_defineProperty(this, "name", "Tree.TreeError");
|
|
4632
4686
|
}
|
|
4633
4687
|
};
|
|
4634
4688
|
/**
|
|
@@ -4636,9 +4690,9 @@ var TreeError = class extends BaseError {
|
|
|
4636
4690
|
* Indicates validation failures (signature, root mismatch, mixed makers).
|
|
4637
4691
|
*/
|
|
4638
4692
|
var EncodeError = class extends BaseError {
|
|
4693
|
+
name = "Tree.EncodeError";
|
|
4639
4694
|
constructor(reason) {
|
|
4640
4695
|
super(`Failed to encode tree: ${reason}`);
|
|
4641
|
-
_defineProperty(this, "name", "Tree.EncodeError");
|
|
4642
4696
|
}
|
|
4643
4697
|
};
|
|
4644
4698
|
/**
|
|
@@ -4646,18 +4700,18 @@ var EncodeError = class extends BaseError {
|
|
|
4646
4700
|
* Indicates payload corruption, version mismatch, or validation failures.
|
|
4647
4701
|
*/
|
|
4648
4702
|
var DecodeError = class extends BaseError {
|
|
4703
|
+
name = "Tree.DecodeError";
|
|
4649
4704
|
constructor(reason) {
|
|
4650
4705
|
super(`Failed to decode tree: ${reason}`);
|
|
4651
|
-
_defineProperty(this, "name", "Tree.DecodeError");
|
|
4652
4706
|
}
|
|
4653
4707
|
};
|
|
4654
4708
|
/**
|
|
4655
4709
|
* Error thrown when an invalid signature domain is supplied.
|
|
4656
4710
|
*/
|
|
4657
4711
|
var SignatureDomainError = class extends BaseError {
|
|
4712
|
+
name = "Tree.SignatureDomainError";
|
|
4658
4713
|
constructor(reason) {
|
|
4659
4714
|
super(`Invalid signature domain: ${reason}`);
|
|
4660
|
-
_defineProperty(this, "name", "Tree.SignatureDomainError");
|
|
4661
4715
|
}
|
|
4662
4716
|
};
|
|
4663
4717
|
|
|
@@ -4815,36 +4869,51 @@ async function getObligations(apiClient, parameters) {
|
|
|
4815
4869
|
};
|
|
4816
4870
|
}
|
|
4817
4871
|
var InvalidUrlError = class extends BaseError {
|
|
4872
|
+
name = "Router.InvalidUrlError";
|
|
4818
4873
|
constructor(url) {
|
|
4819
4874
|
super(`URL "${url}" is not http/https.`);
|
|
4820
|
-
_defineProperty(this, "name", "Router.InvalidUrlError");
|
|
4821
4875
|
}
|
|
4822
4876
|
};
|
|
4823
4877
|
var HttpUnauthorizedError = class extends BaseError {
|
|
4878
|
+
name = "Router.HttpUnauthorizedError";
|
|
4824
4879
|
constructor() {
|
|
4825
4880
|
super("Unauthorized.", { metaMessages: ["Ensure that an API key is provided."] });
|
|
4826
|
-
_defineProperty(this, "name", "Router.HttpUnauthorizedError");
|
|
4827
4881
|
}
|
|
4828
4882
|
};
|
|
4829
4883
|
var HttpForbiddenError = class extends BaseError {
|
|
4884
|
+
name = "Router.HttpForbiddenError";
|
|
4830
4885
|
constructor() {
|
|
4831
4886
|
super("Forbidden.", { metaMessages: ["Ensure that the API key is valid."] });
|
|
4832
|
-
_defineProperty(this, "name", "Router.HttpForbiddenError");
|
|
4833
4887
|
}
|
|
4834
4888
|
};
|
|
4835
4889
|
var HttpRateLimitError = class extends BaseError {
|
|
4890
|
+
name = "Router.HttpRateLimitError";
|
|
4836
4891
|
constructor() {
|
|
4837
4892
|
super("Rate limit exceeded.", { metaMessages: ["The number of allowed requests has been exceeded. You must wait for the rate limit to reset."] });
|
|
4838
|
-
_defineProperty(this, "name", "Router.HttpRateLimitError");
|
|
4839
4893
|
}
|
|
4840
4894
|
};
|
|
4841
4895
|
var HttpGetApiFailedError = class extends BaseError {
|
|
4896
|
+
name = "Router.HttpGetApiFailedError";
|
|
4842
4897
|
constructor(message, { details } = {}) {
|
|
4843
4898
|
super(message, { metaMessages: [details] });
|
|
4844
|
-
_defineProperty(this, "name", "Router.HttpGetApiFailedError");
|
|
4845
4899
|
}
|
|
4846
4900
|
};
|
|
4847
4901
|
|
|
4902
|
+
//#endregion
|
|
4903
|
+
//#region src/observability/TraceHeaders.ts
|
|
4904
|
+
/**
|
|
4905
|
+
* Inject active trace context headers into outgoing HTTP headers.
|
|
4906
|
+
* @param headers - Existing headers for the outgoing request.
|
|
4907
|
+
* @returns Headers enriched with active trace context.
|
|
4908
|
+
*/
|
|
4909
|
+
function withActiveTraceHeaders(headers) {
|
|
4910
|
+
const enrichedHeaders = new Headers(headers);
|
|
4911
|
+
const carrier = {};
|
|
4912
|
+
propagation.inject(context.active(), carrier);
|
|
4913
|
+
for (const [key, value] of Object.entries(carrier)) enrichedHeaders.set(key, value);
|
|
4914
|
+
return enrichedHeaders;
|
|
4915
|
+
}
|
|
4916
|
+
|
|
4848
4917
|
//#endregion
|
|
4849
4918
|
//#region src/gatekeeper/Client.ts
|
|
4850
4919
|
var Client_exports = /* @__PURE__ */ __exportAll({ createHttpClient: () => createHttpClient });
|
|
@@ -4865,7 +4934,7 @@ function createHttpClient(config) {
|
|
|
4865
4934
|
try {
|
|
4866
4935
|
return await fetchFn(`${baseUrl}${path}`, {
|
|
4867
4936
|
...init,
|
|
4868
|
-
headers: mergeHeaders(baseHeaders, init.headers),
|
|
4937
|
+
headers: withActiveTraceHeaders(mergeHeaders(baseHeaders, init.headers)),
|
|
4869
4938
|
signal: controller.signal
|
|
4870
4939
|
});
|
|
4871
4940
|
} finally {
|
|
@@ -5117,7 +5186,7 @@ const collateralAssets = {
|
|
|
5117
5186
|
"0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0"
|
|
5118
5187
|
]
|
|
5119
5188
|
};
|
|
5120
|
-
const oracles = {
|
|
5189
|
+
const oracles$1 = {
|
|
5121
5190
|
[ChainId.ETHEREUM.toString()]: [
|
|
5122
5191
|
"0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
5123
5192
|
"0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
|
|
@@ -5139,6 +5208,7 @@ const oracles = {
|
|
|
5139
5208
|
],
|
|
5140
5209
|
[ChainId["ETHEREUM-VIRTUAL-TESTNET"].toString()]: [
|
|
5141
5210
|
"0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
5211
|
+
"0xEeee770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
5142
5212
|
"0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
|
|
5143
5213
|
"0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
|
|
5144
5214
|
"0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
|
|
@@ -5147,6 +5217,7 @@ const oracles = {
|
|
|
5147
5217
|
],
|
|
5148
5218
|
[ChainId.ANVIL.toString()]: [
|
|
5149
5219
|
"0xDddd770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
5220
|
+
"0xEeee770BADd886dF3864029e4B377B5F6a2B6b83",
|
|
5150
5221
|
"0x9CB3f4276bcD149b3668e1a645a964bC12877b89",
|
|
5151
5222
|
"0x48F7E36EB6B826B2dF4B2E630B62Cd25e89E40e2",
|
|
5152
5223
|
"0x6Eb9F4128CeBc8B885A4d8562Db1Addf097f7348",
|
|
@@ -5157,30 +5228,626 @@ const oracles = {
|
|
|
5157
5228
|
const configs = {
|
|
5158
5229
|
ethereum: {
|
|
5159
5230
|
callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
|
|
5160
|
-
maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
|
|
5231
|
+
maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
|
|
5232
|
+
minDuration: 10
|
|
5161
5233
|
},
|
|
5162
5234
|
base: {
|
|
5163
5235
|
callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
|
|
5164
|
-
maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
|
|
5236
|
+
maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
|
|
5237
|
+
minDuration: 10
|
|
5165
5238
|
},
|
|
5166
5239
|
"ethereum-virtual-testnet": {
|
|
5167
5240
|
callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
|
|
5168
|
-
maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
|
|
5241
|
+
maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
|
|
5242
|
+
minDuration: 10
|
|
5169
5243
|
},
|
|
5170
5244
|
anvil: {
|
|
5171
5245
|
callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
|
|
5172
|
-
maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek]
|
|
5246
|
+
maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek],
|
|
5247
|
+
minDuration: 10
|
|
5248
|
+
}
|
|
5249
|
+
};
|
|
5250
|
+
|
|
5251
|
+
//#endregion
|
|
5252
|
+
//#region src/utils/retry.ts
|
|
5253
|
+
const retry = async (fn, attempts = 3, delayMs = 50) => {
|
|
5254
|
+
let lastErr;
|
|
5255
|
+
for (let i = 0; i < attempts; i++) try {
|
|
5256
|
+
return await fn();
|
|
5257
|
+
} catch (err) {
|
|
5258
|
+
lastErr = err;
|
|
5259
|
+
if (i < attempts - 1) await new Promise((r) => setTimeout(r, delayMs));
|
|
5260
|
+
}
|
|
5261
|
+
throw lastErr;
|
|
5262
|
+
};
|
|
5263
|
+
|
|
5264
|
+
//#endregion
|
|
5265
|
+
//#region src/utils/batchMulticall.ts
|
|
5266
|
+
/**
|
|
5267
|
+
* Helper function to execute multicall in batches with retry logic.
|
|
5268
|
+
* Abstracts the common pattern of batching calls, retrying, and collecting results.
|
|
5269
|
+
*
|
|
5270
|
+
* @param parameters - Configuration for batched multicall
|
|
5271
|
+
* @returns Promise resolving to flattened array of results
|
|
5272
|
+
*/
|
|
5273
|
+
async function batchMulticall(parameters) {
|
|
5274
|
+
const { client, calls, batchSize, retryAttempts, retryDelayMs, blockNumber } = parameters;
|
|
5275
|
+
const results = [];
|
|
5276
|
+
for (const callsBatch of batch$1(calls, batchSize)) {
|
|
5277
|
+
const batchResults = await retry(() => multicall(client, {
|
|
5278
|
+
allowFailure: false,
|
|
5279
|
+
contracts: callsBatch,
|
|
5280
|
+
...blockNumber ? { blockNumber } : {}
|
|
5281
|
+
}), retryAttempts, retryDelayMs);
|
|
5282
|
+
results.push(...batchResults);
|
|
5173
5283
|
}
|
|
5284
|
+
return results;
|
|
5285
|
+
}
|
|
5286
|
+
|
|
5287
|
+
//#endregion
|
|
5288
|
+
//#region src/utils/Group.ts
|
|
5289
|
+
var Group_exports = /* @__PURE__ */ __exportAll({ fromNumber: () => fromNumber });
|
|
5290
|
+
/**
|
|
5291
|
+
* Creates a bytes32 group identifier from a number.
|
|
5292
|
+
* @param n - A non-negative integer.
|
|
5293
|
+
* @throws {Error} If n is negative or not an integer.
|
|
5294
|
+
*/
|
|
5295
|
+
const fromNumber = (n) => {
|
|
5296
|
+
if (!Number.isInteger(n)) throw new Error(`Group.fromNumber: expected integer, got ${n}`);
|
|
5297
|
+
if (n < 0) throw new Error(`Group.fromNumber: expected non-negative, got ${n}`);
|
|
5298
|
+
return pad(`0x${n.toString(16)}`, { size: 32 });
|
|
5174
5299
|
};
|
|
5175
5300
|
|
|
5301
|
+
//#endregion
|
|
5302
|
+
//#region src/utils/lazy.ts
|
|
5303
|
+
/**
|
|
5304
|
+
* Transform a polling function into an async generator.
|
|
5305
|
+
* @param fn - The polling function to transform.
|
|
5306
|
+
* @returns An async generator.
|
|
5307
|
+
*/
|
|
5308
|
+
function lazy(pollFn) {
|
|
5309
|
+
return () => (async function* () {
|
|
5310
|
+
let active = true;
|
|
5311
|
+
let resolveNext = null;
|
|
5312
|
+
const queue = [];
|
|
5313
|
+
const wait = () => new Promise((resolve) => {
|
|
5314
|
+
resolveNext = resolve;
|
|
5315
|
+
});
|
|
5316
|
+
const emit = (item) => {
|
|
5317
|
+
queue.push(item);
|
|
5318
|
+
resolveNext?.();
|
|
5319
|
+
resolveNext = null;
|
|
5320
|
+
};
|
|
5321
|
+
let unpoll = null;
|
|
5322
|
+
const stop = () => {
|
|
5323
|
+
active = false;
|
|
5324
|
+
unpoll?.();
|
|
5325
|
+
resolveNext?.();
|
|
5326
|
+
resolveNext = null;
|
|
5327
|
+
};
|
|
5328
|
+
unpoll = pollFn(emit, { stop });
|
|
5329
|
+
try {
|
|
5330
|
+
while (active) {
|
|
5331
|
+
if (queue.length === 0) await wait();
|
|
5332
|
+
while (queue.length > 0 && active) yield queue.shift();
|
|
5333
|
+
}
|
|
5334
|
+
} finally {
|
|
5335
|
+
stop();
|
|
5336
|
+
}
|
|
5337
|
+
})();
|
|
5338
|
+
}
|
|
5339
|
+
|
|
5340
|
+
//#endregion
|
|
5341
|
+
//#region src/utils/wait.ts
|
|
5342
|
+
async function wait(time) {
|
|
5343
|
+
return new Promise((res) => setTimeout(res, time));
|
|
5344
|
+
}
|
|
5345
|
+
|
|
5346
|
+
//#endregion
|
|
5347
|
+
//#region src/utils/poll.ts
|
|
5348
|
+
/**
|
|
5349
|
+
* Polls a function at a specified interval.
|
|
5350
|
+
* Inspired by https://github.com/wevm/viem/blob/845994d20275d08ff892018e237a4b599eeefb6a/src/utils/poll.ts
|
|
5351
|
+
*/
|
|
5352
|
+
function poll(fn, { interval }) {
|
|
5353
|
+
let active = true;
|
|
5354
|
+
const unwatch = () => active = false;
|
|
5355
|
+
const watch = async () => {
|
|
5356
|
+
while (active) {
|
|
5357
|
+
const delay = await interval();
|
|
5358
|
+
if (!active) break;
|
|
5359
|
+
await wait(delay);
|
|
5360
|
+
if (!active) break;
|
|
5361
|
+
await fn({ unpoll: unwatch });
|
|
5362
|
+
}
|
|
5363
|
+
};
|
|
5364
|
+
watch();
|
|
5365
|
+
return unwatch;
|
|
5366
|
+
}
|
|
5367
|
+
|
|
5368
|
+
//#endregion
|
|
5369
|
+
//#region src/utils/time.ts
|
|
5370
|
+
var time_exports = /* @__PURE__ */ __exportAll({
|
|
5371
|
+
max: () => max,
|
|
5372
|
+
now: () => now
|
|
5373
|
+
});
|
|
5374
|
+
function now() {
|
|
5375
|
+
return Math.floor(Date.now() / 1e3);
|
|
5376
|
+
}
|
|
5377
|
+
function max() {
|
|
5378
|
+
return 0x77e772392b600000;
|
|
5379
|
+
}
|
|
5380
|
+
|
|
5381
|
+
//#endregion
|
|
5382
|
+
//#region src/utils/index.ts
|
|
5383
|
+
var utils_exports = /* @__PURE__ */ __exportAll({
|
|
5384
|
+
BaseError: () => BaseError,
|
|
5385
|
+
Group: () => Group_exports,
|
|
5386
|
+
Random: () => Random_exports,
|
|
5387
|
+
ReorgError: () => ReorgError,
|
|
5388
|
+
Time: () => time_exports,
|
|
5389
|
+
atMostOneNonZero: () => atMostOneNonZero,
|
|
5390
|
+
batch: () => batch$1,
|
|
5391
|
+
batchMulticall: () => batchMulticall,
|
|
5392
|
+
fromSnakeCase: () => fromSnakeCase$3,
|
|
5393
|
+
lazy: () => lazy,
|
|
5394
|
+
max: () => max$1,
|
|
5395
|
+
min: () => min,
|
|
5396
|
+
poll: () => poll,
|
|
5397
|
+
retry: () => retry,
|
|
5398
|
+
stringifyBigint: () => stringifyBigint,
|
|
5399
|
+
toSnakeCase: () => toSnakeCase$1,
|
|
5400
|
+
wait: () => wait
|
|
5401
|
+
});
|
|
5402
|
+
|
|
5403
|
+
//#endregion
|
|
5404
|
+
//#region src/database/drizzle/VERSION.ts
|
|
5405
|
+
const VERSION = "router_v1.13";
|
|
5406
|
+
|
|
5407
|
+
//#endregion
|
|
5408
|
+
//#region src/database/drizzle/schema.ts
|
|
5409
|
+
const s = pgSchema(VERSION);
|
|
5410
|
+
var EnumTableName = /* @__PURE__ */ function(EnumTableName) {
|
|
5411
|
+
EnumTableName["OBLIGATIONS"] = "obligations";
|
|
5412
|
+
EnumTableName["OBLIGATION_ID_KEYS"] = "obligation_id_keys";
|
|
5413
|
+
EnumTableName["GROUPS"] = "groups";
|
|
5414
|
+
EnumTableName["CONSUMED_EVENTS"] = "consumed_events";
|
|
5415
|
+
EnumTableName["OBLIGATION_COLLATERALS_V2"] = "obligation_collaterals_v2";
|
|
5416
|
+
EnumTableName["ORACLES"] = "oracles";
|
|
5417
|
+
EnumTableName["OFFERS"] = "offers";
|
|
5418
|
+
EnumTableName["OFFERS_CALLBACKS"] = "offers_callbacks";
|
|
5419
|
+
EnumTableName["CALLBACKS"] = "callbacks";
|
|
5420
|
+
EnumTableName["POSITIONS"] = "positions";
|
|
5421
|
+
EnumTableName["TRANSFERS"] = "transfers";
|
|
5422
|
+
EnumTableName["VALIDATIONS"] = "validations";
|
|
5423
|
+
EnumTableName["COLLECTORS"] = "collectors";
|
|
5424
|
+
EnumTableName["CHAINS"] = "chains";
|
|
5425
|
+
EnumTableName["LOTS"] = "lots";
|
|
5426
|
+
EnumTableName["LOTS_POSITIONS"] = "lots_positions";
|
|
5427
|
+
EnumTableName["OFFSETS"] = "offsets";
|
|
5428
|
+
EnumTableName["TREES"] = "trees";
|
|
5429
|
+
EnumTableName["MERKLE_PATHS"] = "merkle_paths";
|
|
5430
|
+
return EnumTableName;
|
|
5431
|
+
}(EnumTableName || {});
|
|
5432
|
+
const TABLE_NAMES = Object.values(EnumTableName);
|
|
5433
|
+
const VERSIONED_TABLE_NAMES = TABLE_NAMES.map((table) => `"${VERSION}"."${table}"`);
|
|
5434
|
+
const obligations = s.table(EnumTableName.OBLIGATIONS, {
|
|
5435
|
+
obligationKey: varchar("obligation_key", { length: 66 }).primaryKey(),
|
|
5436
|
+
loanToken: varchar("loan_token", { length: 42 }).notNull(),
|
|
5437
|
+
maturity: integer("maturity").notNull()
|
|
5438
|
+
});
|
|
5439
|
+
const obligationIdKeys = s.table(EnumTableName.OBLIGATION_ID_KEYS, {
|
|
5440
|
+
obligationId: varchar("obligation_id", { length: 42 }).primaryKey(),
|
|
5441
|
+
obligationKey: varchar("obligation_key", { length: 66 }).notNull().references(() => obligations.obligationKey, { onDelete: "cascade" }),
|
|
5442
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5443
|
+
morphoV2: varchar("morpho_v2", { length: 42 }).notNull()
|
|
5444
|
+
}, (table) => [index("obligation_id_keys_obligation_key_idx").on(table.obligationKey), index("obligation_id_keys_chain_id_idx").on(table.chainId)]);
|
|
5445
|
+
const groups = s.table(EnumTableName.GROUPS, {
|
|
5446
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5447
|
+
maker: varchar("maker", { length: 42 }).notNull(),
|
|
5448
|
+
group: varchar("group", { length: 66 }).notNull(),
|
|
5449
|
+
consumed: numeric("consumed", {
|
|
5450
|
+
precision: 78,
|
|
5451
|
+
scale: 0
|
|
5452
|
+
}).notNull(),
|
|
5453
|
+
blockNumber: bigint("block_number", { mode: "number" }).notNull(),
|
|
5454
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
5455
|
+
}, (table) => [primaryKey({
|
|
5456
|
+
columns: [
|
|
5457
|
+
table.chainId,
|
|
5458
|
+
table.maker,
|
|
5459
|
+
table.group
|
|
5460
|
+
],
|
|
5461
|
+
name: "groups_pk"
|
|
5462
|
+
}), index("groups_chain_id_maker_group_consumed_idx").on(table.chainId, table.maker, table.group, table.consumed)]);
|
|
5463
|
+
const consumedEvents = s.table(EnumTableName.CONSUMED_EVENTS, {
|
|
5464
|
+
eventId: varchar("event_id", { length: 128 }).primaryKey(),
|
|
5465
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5466
|
+
maker: varchar("maker", { length: 42 }).notNull(),
|
|
5467
|
+
group: varchar("group", { length: 66 }).notNull(),
|
|
5468
|
+
amount: numeric("amount", {
|
|
5469
|
+
precision: 78,
|
|
5470
|
+
scale: 0
|
|
5471
|
+
}).notNull(),
|
|
5472
|
+
blockNumber: bigint("block_number", { mode: "number" }).notNull(),
|
|
5473
|
+
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
5474
|
+
}, (t) => [
|
|
5475
|
+
foreignKey({
|
|
5476
|
+
columns: [
|
|
5477
|
+
t.chainId,
|
|
5478
|
+
t.maker,
|
|
5479
|
+
t.group
|
|
5480
|
+
],
|
|
5481
|
+
foreignColumns: [
|
|
5482
|
+
groups.chainId,
|
|
5483
|
+
groups.maker,
|
|
5484
|
+
groups.group
|
|
5485
|
+
],
|
|
5486
|
+
name: "consumed_events_groups_fk"
|
|
5487
|
+
}).onDelete("cascade"),
|
|
5488
|
+
index("consumed_events_group_idx").on(t.chainId, t.maker, t.group),
|
|
5489
|
+
index("consumed_events_block_number_idx").on(t.blockNumber)
|
|
5490
|
+
]);
|
|
5491
|
+
const obligationCollateralsV2 = s.table(EnumTableName.OBLIGATION_COLLATERALS_V2, {
|
|
5492
|
+
obligationKey: varchar("obligation_key", { length: 66 }).notNull().references(() => obligations.obligationKey, { onDelete: "cascade" }),
|
|
5493
|
+
asset: varchar("asset", { length: 42 }).notNull(),
|
|
5494
|
+
oracleAddress: varchar("oracle_address", { length: 42 }).notNull(),
|
|
5495
|
+
lltv: bigint("lltv", { mode: "bigint" }).notNull(),
|
|
5496
|
+
collateralIndex: integer("collateral_index").notNull(),
|
|
5497
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
5498
|
+
}, (table) => [
|
|
5499
|
+
primaryKey({
|
|
5500
|
+
columns: [table.obligationKey, table.asset],
|
|
5501
|
+
name: "obligation_collaterals_v2_pk"
|
|
5502
|
+
}),
|
|
5503
|
+
index("obligation_collaterals_v2_obligation_key_idx").on(table.obligationKey),
|
|
5504
|
+
index("obligation_collaterals_v2_oracle_address_idx").on(table.oracleAddress)
|
|
5505
|
+
]);
|
|
5506
|
+
const oracles = s.table(EnumTableName.ORACLES, {
|
|
5507
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5508
|
+
address: varchar("address", { length: 42 }).notNull(),
|
|
5509
|
+
price: numeric("price", {
|
|
5510
|
+
precision: 78,
|
|
5511
|
+
scale: 0
|
|
5512
|
+
}),
|
|
5513
|
+
blockNumber: bigint("block_number", { mode: "number" }).notNull(),
|
|
5514
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
5515
|
+
}, (table) => [primaryKey({
|
|
5516
|
+
columns: [table.chainId, table.address],
|
|
5517
|
+
name: "oracles_pk"
|
|
5518
|
+
})]);
|
|
5519
|
+
const offers = s.table(EnumTableName.OFFERS, {
|
|
5520
|
+
hash: varchar("hash", { length: 66 }).notNull(),
|
|
5521
|
+
obligationId: varchar("obligation_id", { length: 42 }).notNull().references(() => obligationIdKeys.obligationId, { onDelete: "cascade" }),
|
|
5522
|
+
assets: numeric("assets", {
|
|
5523
|
+
precision: 78,
|
|
5524
|
+
scale: 0
|
|
5525
|
+
}).notNull(),
|
|
5526
|
+
obligationUnits: numeric("obligation_units", {
|
|
5527
|
+
precision: 78,
|
|
5528
|
+
scale: 0
|
|
5529
|
+
}).notNull().default("0"),
|
|
5530
|
+
obligationShares: numeric("obligation_shares", {
|
|
5531
|
+
precision: 78,
|
|
5532
|
+
scale: 0
|
|
5533
|
+
}).notNull().default("0"),
|
|
5534
|
+
tick: integer("tick").notNull(),
|
|
5535
|
+
maturity: integer("maturity").notNull(),
|
|
5536
|
+
expiry: integer("expiry").notNull(),
|
|
5537
|
+
start: integer("start").notNull(),
|
|
5538
|
+
groupChainId: bigint("group_chain_id", { mode: "number" }).$type().notNull(),
|
|
5539
|
+
groupMaker: varchar("group_maker", { length: 42 }).notNull(),
|
|
5540
|
+
group: varchar("group_group", { length: 66 }).notNull(),
|
|
5541
|
+
session: varchar("session", { length: 66 }).notNull(),
|
|
5542
|
+
buy: boolean("buy").notNull(),
|
|
5543
|
+
callbackAddress: varchar("callback_address", { length: 42 }).notNull(),
|
|
5544
|
+
callbackData: text("callback_data").notNull(),
|
|
5545
|
+
receiverIfMakerIsSeller: varchar("receiver_if_maker_is_seller", { length: 42 }),
|
|
5546
|
+
blockNumber: bigint("block_number", { mode: "number" }).notNull(),
|
|
5547
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
5548
|
+
}, (table) => [
|
|
5549
|
+
primaryKey({
|
|
5550
|
+
columns: [table.hash, table.obligationId],
|
|
5551
|
+
name: "offers_pk"
|
|
5552
|
+
}),
|
|
5553
|
+
foreignKey({
|
|
5554
|
+
columns: [
|
|
5555
|
+
table.groupChainId,
|
|
5556
|
+
table.groupMaker,
|
|
5557
|
+
table.group
|
|
5558
|
+
],
|
|
5559
|
+
foreignColumns: [
|
|
5560
|
+
groups.chainId,
|
|
5561
|
+
groups.maker,
|
|
5562
|
+
groups.group
|
|
5563
|
+
],
|
|
5564
|
+
name: "offers_groups_fk"
|
|
5565
|
+
}).onDelete("cascade"),
|
|
5566
|
+
index("offers_group_fk_idx").on(table.groupChainId, table.groupMaker, table.group),
|
|
5567
|
+
index("offers_group_and_hash_idx").on(table.groupChainId, table.groupMaker, table.group, table.hash),
|
|
5568
|
+
index("offers_obligation_id_side_idx").on(table.obligationId, table.buy)
|
|
5569
|
+
]);
|
|
5570
|
+
const offersCallbacks = s.table(EnumTableName.OFFERS_CALLBACKS, {
|
|
5571
|
+
offerHash: varchar("offer_hash", { length: 66 }).notNull(),
|
|
5572
|
+
obligationId: varchar("obligation_id", { length: 42 }).notNull(),
|
|
5573
|
+
callbackId: varchar("callback_id", { length: 66 })
|
|
5574
|
+
}, (table) => [foreignKey({
|
|
5575
|
+
columns: [table.offerHash, table.obligationId],
|
|
5576
|
+
foreignColumns: [offers.hash, offers.obligationId],
|
|
5577
|
+
name: "offers_callbacks_offer_fk"
|
|
5578
|
+
}).onDelete("cascade"), primaryKey({
|
|
5579
|
+
columns: [
|
|
5580
|
+
table.offerHash,
|
|
5581
|
+
table.obligationId,
|
|
5582
|
+
table.callbackId
|
|
5583
|
+
],
|
|
5584
|
+
name: "offers_callbacks_pk"
|
|
5585
|
+
})]);
|
|
5586
|
+
const CallbackTypes = s.enum("callback_type", Object.values(CallbackType));
|
|
5587
|
+
const callbacks = s.table(EnumTableName.CALLBACKS, {
|
|
5588
|
+
id: varchar("id", { length: 66 }).primaryKey(),
|
|
5589
|
+
positionChainId: bigint("position_chain_id", { mode: "number" }).$type().notNull(),
|
|
5590
|
+
positionContract: varchar("position_contract", { length: 66 }).notNull(),
|
|
5591
|
+
positionUser: varchar("position_user", { length: 42 }).notNull(),
|
|
5592
|
+
positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
|
|
5593
|
+
type: CallbackTypes("type").notNull()
|
|
5594
|
+
});
|
|
5595
|
+
const lotsPositions = s.table(EnumTableName.LOTS_POSITIONS, {
|
|
5596
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5597
|
+
contract: varchar("contract", { length: 66 }).notNull(),
|
|
5598
|
+
user: varchar("user", { length: 42 }).notNull(),
|
|
5599
|
+
positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" })
|
|
5600
|
+
}, (table) => [primaryKey({
|
|
5601
|
+
columns: [
|
|
5602
|
+
table.chainId,
|
|
5603
|
+
table.contract,
|
|
5604
|
+
table.user
|
|
5605
|
+
],
|
|
5606
|
+
name: "lots_positions_pk"
|
|
5607
|
+
})]);
|
|
5608
|
+
const lots = s.table(EnumTableName.LOTS, {
|
|
5609
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5610
|
+
user: varchar("user", { length: 42 }).notNull(),
|
|
5611
|
+
contract: varchar("contract", { length: 66 }).notNull(),
|
|
5612
|
+
group: varchar("group", { length: 66 }).notNull(),
|
|
5613
|
+
obligationId: varchar("obligation_id", { length: 42 }).notNull(),
|
|
5614
|
+
lower: numeric("lower", {
|
|
5615
|
+
precision: 78,
|
|
5616
|
+
scale: 0
|
|
5617
|
+
}).notNull(),
|
|
5618
|
+
upper: numeric("upper", {
|
|
5619
|
+
precision: 78,
|
|
5620
|
+
scale: 0
|
|
5621
|
+
}).notNull()
|
|
5622
|
+
}, (table) => [
|
|
5623
|
+
primaryKey({
|
|
5624
|
+
columns: [
|
|
5625
|
+
table.chainId,
|
|
5626
|
+
table.user,
|
|
5627
|
+
table.contract,
|
|
5628
|
+
table.group,
|
|
5629
|
+
table.obligationId
|
|
5630
|
+
],
|
|
5631
|
+
name: "lots_pk"
|
|
5632
|
+
}),
|
|
5633
|
+
foreignKey({
|
|
5634
|
+
columns: [
|
|
5635
|
+
table.chainId,
|
|
5636
|
+
table.contract,
|
|
5637
|
+
table.user
|
|
5638
|
+
],
|
|
5639
|
+
foreignColumns: [
|
|
5640
|
+
lotsPositions.chainId,
|
|
5641
|
+
lotsPositions.contract,
|
|
5642
|
+
lotsPositions.user
|
|
5643
|
+
],
|
|
5644
|
+
name: "lots_lots_positions_fk"
|
|
5645
|
+
}).onDelete("cascade"),
|
|
5646
|
+
foreignKey({
|
|
5647
|
+
columns: [
|
|
5648
|
+
table.chainId,
|
|
5649
|
+
table.user,
|
|
5650
|
+
table.group
|
|
5651
|
+
],
|
|
5652
|
+
foreignColumns: [
|
|
5653
|
+
groups.chainId,
|
|
5654
|
+
groups.maker,
|
|
5655
|
+
groups.group
|
|
5656
|
+
],
|
|
5657
|
+
name: "lots_groups_fk"
|
|
5658
|
+
}).onDelete("cascade")
|
|
5659
|
+
]);
|
|
5660
|
+
const offsets = s.table(EnumTableName.OFFSETS, {
|
|
5661
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5662
|
+
user: varchar("user", { length: 42 }).notNull(),
|
|
5663
|
+
contract: varchar("contract", { length: 66 }).notNull(),
|
|
5664
|
+
group: varchar("group", { length: 66 }).notNull(),
|
|
5665
|
+
obligationId: varchar("obligation_id", { length: 42 }).notNull(),
|
|
5666
|
+
value: numeric("value", {
|
|
5667
|
+
precision: 78,
|
|
5668
|
+
scale: 0
|
|
5669
|
+
}).notNull()
|
|
5670
|
+
}, (table) => [primaryKey({
|
|
5671
|
+
columns: [
|
|
5672
|
+
table.chainId,
|
|
5673
|
+
table.user,
|
|
5674
|
+
table.contract,
|
|
5675
|
+
table.group,
|
|
5676
|
+
table.obligationId
|
|
5677
|
+
],
|
|
5678
|
+
name: "offsets_pk"
|
|
5679
|
+
}), foreignKey({
|
|
5680
|
+
columns: [
|
|
5681
|
+
table.chainId,
|
|
5682
|
+
table.contract,
|
|
5683
|
+
table.user
|
|
5684
|
+
],
|
|
5685
|
+
foreignColumns: [
|
|
5686
|
+
lotsPositions.chainId,
|
|
5687
|
+
lotsPositions.contract,
|
|
5688
|
+
lotsPositions.user
|
|
5689
|
+
],
|
|
5690
|
+
name: "offsets_lots_positions_fk"
|
|
5691
|
+
}).onDelete("cascade")]);
|
|
5692
|
+
const PositionTypes = s.enum("position_type", Object.values(Type));
|
|
5693
|
+
const positionTypes = s.table("position_types", {
|
|
5694
|
+
id: serial("id").primaryKey(),
|
|
5695
|
+
type: PositionTypes("type").notNull()
|
|
5696
|
+
});
|
|
5697
|
+
const positions = s.table(EnumTableName.POSITIONS, {
|
|
5698
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5699
|
+
contract: varchar("contract", { length: 66 }).notNull(),
|
|
5700
|
+
user: varchar("user", { length: 42 }).notNull(),
|
|
5701
|
+
positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
|
|
5702
|
+
balance: numeric("balance", {
|
|
5703
|
+
precision: 78,
|
|
5704
|
+
scale: 0
|
|
5705
|
+
}),
|
|
5706
|
+
asset: varchar("asset", { length: 42 }).notNull(),
|
|
5707
|
+
blockNumber: bigint("block_number", { mode: "number" }).notNull(),
|
|
5708
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
5709
|
+
}, (table) => [primaryKey({
|
|
5710
|
+
columns: [
|
|
5711
|
+
table.chainId,
|
|
5712
|
+
table.contract,
|
|
5713
|
+
table.user,
|
|
5714
|
+
table.positionTypeId,
|
|
5715
|
+
table.asset
|
|
5716
|
+
],
|
|
5717
|
+
name: "positions_pk"
|
|
5718
|
+
})]);
|
|
5719
|
+
const transfers = s.table(EnumTableName.TRANSFERS, {
|
|
5720
|
+
eventId: varchar("event_id", { length: 128 }).primaryKey(),
|
|
5721
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5722
|
+
contract: varchar("contract", { length: 66 }).notNull(),
|
|
5723
|
+
from: varchar("from", { length: 42 }).notNull(),
|
|
5724
|
+
to: varchar("to", { length: 42 }).notNull(),
|
|
5725
|
+
value: numeric("value", {
|
|
5726
|
+
precision: 78,
|
|
5727
|
+
scale: 0
|
|
5728
|
+
}).notNull(),
|
|
5729
|
+
positionTypeId: integer("position_type_id").notNull().references(() => positionTypes.id, { onDelete: "no action" }),
|
|
5730
|
+
asset: varchar("asset", { length: 42 }).notNull(),
|
|
5731
|
+
blockNumber: bigint("block_number", { mode: "number" }).notNull(),
|
|
5732
|
+
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
5733
|
+
}, (table) => [
|
|
5734
|
+
foreignKey({
|
|
5735
|
+
columns: [
|
|
5736
|
+
table.chainId,
|
|
5737
|
+
table.contract,
|
|
5738
|
+
table.from,
|
|
5739
|
+
table.positionTypeId,
|
|
5740
|
+
table.asset
|
|
5741
|
+
],
|
|
5742
|
+
foreignColumns: [
|
|
5743
|
+
positions.chainId,
|
|
5744
|
+
positions.contract,
|
|
5745
|
+
positions.user,
|
|
5746
|
+
positions.positionTypeId,
|
|
5747
|
+
positions.asset
|
|
5748
|
+
],
|
|
5749
|
+
name: "transfers_positions_from_fk"
|
|
5750
|
+
}).onDelete("cascade"),
|
|
5751
|
+
foreignKey({
|
|
5752
|
+
columns: [
|
|
5753
|
+
table.chainId,
|
|
5754
|
+
table.contract,
|
|
5755
|
+
table.to,
|
|
5756
|
+
table.positionTypeId,
|
|
5757
|
+
table.asset
|
|
5758
|
+
],
|
|
5759
|
+
foreignColumns: [
|
|
5760
|
+
positions.chainId,
|
|
5761
|
+
positions.contract,
|
|
5762
|
+
positions.user,
|
|
5763
|
+
positions.positionTypeId,
|
|
5764
|
+
positions.asset
|
|
5765
|
+
],
|
|
5766
|
+
name: "transfers_positions_to_fk"
|
|
5767
|
+
}).onDelete("cascade"),
|
|
5768
|
+
index("transfers_chain_contract_user_idx").on(table.chainId, table.contract, table.from, table.to, table.blockNumber),
|
|
5769
|
+
index("transfers_chain_type_block_idx").on(table.chainId, table.positionTypeId, table.blockNumber)
|
|
5770
|
+
]);
|
|
5771
|
+
const StatusCode = s.enum("status_code", Object.values(Status));
|
|
5772
|
+
const status = s.table("status", {
|
|
5773
|
+
id: serial("id").primaryKey(),
|
|
5774
|
+
code: StatusCode("code").unique()
|
|
5775
|
+
});
|
|
5776
|
+
const validations = s.table("validations", {
|
|
5777
|
+
offerHash: varchar("offer_hash", { length: 66 }).notNull(),
|
|
5778
|
+
obligationId: varchar("obligation_id", { length: 42 }).notNull(),
|
|
5779
|
+
statusId: integer("status_id").notNull().references(() => status.id, { onDelete: "no action" }),
|
|
5780
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
5781
|
+
}, (table) => [primaryKey({
|
|
5782
|
+
columns: [table.offerHash, table.obligationId],
|
|
5783
|
+
name: "validations_pk"
|
|
5784
|
+
}), foreignKey({
|
|
5785
|
+
columns: [table.offerHash, table.obligationId],
|
|
5786
|
+
foreignColumns: [offers.hash, offers.obligationId],
|
|
5787
|
+
name: "validations_offer_fk"
|
|
5788
|
+
}).onDelete("cascade")]);
|
|
5789
|
+
const collectors = s.table(EnumTableName.COLLECTORS, {
|
|
5790
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull().references(() => chains.chainId, { onDelete: "no action" }),
|
|
5791
|
+
name: text("name").$type().notNull(),
|
|
5792
|
+
blockNumber: bigint("block_number", { mode: "number" }).notNull(),
|
|
5793
|
+
epoch: numeric("epoch", {
|
|
5794
|
+
precision: 78,
|
|
5795
|
+
scale: 0
|
|
5796
|
+
}).default("0").notNull(),
|
|
5797
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
5798
|
+
}, (table) => [uniqueIndex("collectors_chain_name_idx").on(table.chainId, table.name)]);
|
|
5799
|
+
const chains = s.table(EnumTableName.CHAINS, {
|
|
5800
|
+
chainId: bigint("chain_id", { mode: "number" }).$type().notNull(),
|
|
5801
|
+
blockNumber: bigint("block_number", { mode: "number" }).notNull(),
|
|
5802
|
+
epoch: numeric("epoch", {
|
|
5803
|
+
precision: 78,
|
|
5804
|
+
scale: 0
|
|
5805
|
+
}).default("0").notNull(),
|
|
5806
|
+
updatedAt: timestamp("updated_at").defaultNow().notNull()
|
|
5807
|
+
}, (table) => [uniqueIndex("chains_chain_id_idx").on(table.chainId)]);
|
|
5808
|
+
const trees = s.table(EnumTableName.TREES, {
|
|
5809
|
+
root: varchar("root", { length: 66 }).primaryKey(),
|
|
5810
|
+
rootSignature: varchar("root_signature", { length: 132 }).notNull(),
|
|
5811
|
+
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
5812
|
+
});
|
|
5813
|
+
const merklePaths = s.table(EnumTableName.MERKLE_PATHS, {
|
|
5814
|
+
offerHash: varchar("offer_hash", { length: 66 }).notNull(),
|
|
5815
|
+
obligationId: varchar("obligation_id", { length: 42 }).notNull(),
|
|
5816
|
+
treeRoot: varchar("tree_root", { length: 66 }).notNull().references(() => trees.root, { onDelete: "cascade" }),
|
|
5817
|
+
proofNodes: text("proof_nodes").notNull(),
|
|
5818
|
+
createdAt: timestamp("created_at").defaultNow().notNull()
|
|
5819
|
+
}, (table) => [
|
|
5820
|
+
primaryKey({
|
|
5821
|
+
columns: [table.offerHash, table.obligationId],
|
|
5822
|
+
name: "merkle_paths_pk"
|
|
5823
|
+
}),
|
|
5824
|
+
foreignKey({
|
|
5825
|
+
columns: [table.offerHash, table.obligationId],
|
|
5826
|
+
foreignColumns: [offers.hash, offers.obligationId],
|
|
5827
|
+
name: "merkle_paths_offer_fk"
|
|
5828
|
+
}).onDelete("cascade"),
|
|
5829
|
+
index("merkle_paths_tree_root_idx").on(table.treeRoot)
|
|
5830
|
+
]);
|
|
5831
|
+
|
|
5832
|
+
//#endregion
|
|
5833
|
+
//#region src/database/domains/Groups.ts
|
|
5834
|
+
/** Build composite key for a group. */
|
|
5835
|
+
function compositeKey(g) {
|
|
5836
|
+
return `${g.chainId}-${g.maker.toLowerCase()}-${g.group.toLowerCase()}`;
|
|
5837
|
+
}
|
|
5838
|
+
|
|
5176
5839
|
//#endregion
|
|
5177
5840
|
//#region src/gatekeeper/Rules.ts
|
|
5178
5841
|
var Rules_exports = /* @__PURE__ */ __exportAll({
|
|
5179
5842
|
amountMutualExclusivity: () => amountMutualExclusivity,
|
|
5180
5843
|
callback: () => callback,
|
|
5181
5844
|
collateralToken: () => collateralToken,
|
|
5845
|
+
groupConsistency: () => groupConsistency,
|
|
5846
|
+
groupImmutability: () => groupImmutability,
|
|
5182
5847
|
loanToken: () => loanToken,
|
|
5183
5848
|
maturity: () => maturity,
|
|
5849
|
+
maxCollaterals: () => maxCollaterals,
|
|
5850
|
+
minDuration: () => minDuration,
|
|
5184
5851
|
oracle: () => oracle,
|
|
5185
5852
|
sameMaker: () => sameMaker
|
|
5186
5853
|
});
|
|
@@ -5247,25 +5914,111 @@ const sameMaker = () => batch("mixed_maker", "Validates that all offers in a bat
|
|
|
5247
5914
|
* At most one of (assets, obligationUnits, obligationShares) can be non-zero.
|
|
5248
5915
|
* Matches contract requirement: `atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)`.
|
|
5249
5916
|
*/
|
|
5917
|
+
/**
|
|
5918
|
+
* A validation rule that checks if the offer duration (expiry - start) meets a minimum threshold.
|
|
5919
|
+
* @param minSeconds - Minimum required duration in seconds.
|
|
5920
|
+
* @returns The issue that was found. If the offer is valid, this will be undefined.
|
|
5921
|
+
*/
|
|
5922
|
+
const minDuration = ({ minSeconds }) => single("min_duration", `Validates that offer duration (expiry - start) is at least ${minSeconds}s`, (offer) => {
|
|
5923
|
+
const duration = offer.expiry - offer.start;
|
|
5924
|
+
if (duration < minSeconds) return { message: `Duration ${duration}s is below minimum ${minSeconds}s` };
|
|
5925
|
+
});
|
|
5926
|
+
/**
|
|
5927
|
+
* A validation rule that checks if an offer exceeds the maximum number of collaterals.
|
|
5928
|
+
* The contract enforces this limit; this rule rejects early to avoid on-chain reverts.
|
|
5929
|
+
* @param max - Maximum allowed collaterals per offer.
|
|
5930
|
+
* @returns The issue that was found. If the offer is valid, this will be undefined.
|
|
5931
|
+
*/
|
|
5932
|
+
const maxCollaterals = ({ max }) => single("max_collaterals", `Validates that an offer has at most ${max} collaterals`, (offer) => {
|
|
5933
|
+
if (offer.collaterals.length > max) return { message: `Offer has ${offer.collaterals.length} collaterals, exceeding the maximum of ${max}` };
|
|
5934
|
+
});
|
|
5250
5935
|
const amountMutualExclusivity = () => single("amount_mutual_exclusivity", "Validates that at most one of (assets, obligationUnits, obligationShares) is non-zero", (offer) => {
|
|
5251
5936
|
if (!atMostOneNonZero(offer.assets, offer.obligationUnits, offer.obligationShares)) return { message: "Inconsistent offer input: at most one of (assets, obligationUnits, obligationShares) must be non-zero" };
|
|
5252
5937
|
});
|
|
5938
|
+
/**
|
|
5939
|
+
* A batch validation rule that ensures all offers within the same group are consistent.
|
|
5940
|
+
* All offers sharing the same group must have the same loan token, assets amount, and side (buy/sell).
|
|
5941
|
+
*/
|
|
5942
|
+
const groupConsistency = () => batch("group_consistency", "Validates that all offers in a group have the same loan token, assets amount, and side", (offers) => {
|
|
5943
|
+
const issues = /* @__PURE__ */ new Map();
|
|
5944
|
+
if (offers.length === 0) return issues;
|
|
5945
|
+
const groupMap = /* @__PURE__ */ new Map();
|
|
5946
|
+
for (let i = 0; i < offers.length; i++) {
|
|
5947
|
+
const key = offers[i].group.toLowerCase();
|
|
5948
|
+
const indices = groupMap.get(key);
|
|
5949
|
+
if (indices) indices.push(i);
|
|
5950
|
+
else groupMap.set(key, [i]);
|
|
5951
|
+
}
|
|
5952
|
+
for (const indices of groupMap.values()) {
|
|
5953
|
+
if (indices.length <= 1) continue;
|
|
5954
|
+
const reference = offers[indices[0]];
|
|
5955
|
+
const refLoanToken = reference.loanToken.toLowerCase();
|
|
5956
|
+
const refAssets = reference.assets;
|
|
5957
|
+
const refBuy = reference.buy;
|
|
5958
|
+
for (let j = 1; j < indices.length; j++) {
|
|
5959
|
+
const idx = indices[j];
|
|
5960
|
+
const offer = offers[idx];
|
|
5961
|
+
if (offer.loanToken.toLowerCase() !== refLoanToken) issues.set(idx, { message: `All offers in a group must have the same loan token. Expected ${reference.loanToken}, got ${offer.loanToken}` });
|
|
5962
|
+
else if (offer.assets !== refAssets) issues.set(idx, { message: `All offers in a group must have the same assets amount. Expected ${refAssets}, got ${offer.assets}` });
|
|
5963
|
+
else if (offer.buy !== refBuy) issues.set(idx, { message: `All offers in a group must be on the same side. Expected ${refBuy ? "buy" : "sell"}, got ${offer.buy ? "buy" : "sell"}` });
|
|
5964
|
+
}
|
|
5965
|
+
}
|
|
5966
|
+
return issues;
|
|
5967
|
+
});
|
|
5968
|
+
/**
|
|
5969
|
+
* A batch validation rule that prevents adding offers to groups that already exist in the database.
|
|
5970
|
+
* Groups are immutable after creation — new offers cannot be added to an existing group.
|
|
5971
|
+
*/
|
|
5972
|
+
const groupImmutability = ({ db, chainId }) => batch("group_immutability", "Validates that offers do not target groups that already exist", async (offers) => {
|
|
5973
|
+
const issues = /* @__PURE__ */ new Map();
|
|
5974
|
+
if (offers.length === 0) return issues;
|
|
5975
|
+
const uniqueGroups = /* @__PURE__ */ new Map();
|
|
5976
|
+
for (const offer of offers) {
|
|
5977
|
+
const key = compositeKey({
|
|
5978
|
+
chainId,
|
|
5979
|
+
maker: offer.maker,
|
|
5980
|
+
group: offer.group
|
|
5981
|
+
});
|
|
5982
|
+
if (!uniqueGroups.has(key)) uniqueGroups.set(key, {
|
|
5983
|
+
chainId,
|
|
5984
|
+
maker: offer.maker,
|
|
5985
|
+
group: offer.group
|
|
5986
|
+
});
|
|
5987
|
+
}
|
|
5988
|
+
const existingKeys = await db.groups.exists(Array.from(uniqueGroups.values()));
|
|
5989
|
+
if (existingKeys.length === 0) return issues;
|
|
5990
|
+
const existingSet = new Set(existingKeys.map((k) => compositeKey(k)));
|
|
5991
|
+
for (let i = 0; i < offers.length; i++) {
|
|
5992
|
+
const offer = offers[i];
|
|
5993
|
+
const key = compositeKey({
|
|
5994
|
+
chainId,
|
|
5995
|
+
maker: offer.maker,
|
|
5996
|
+
group: offer.group
|
|
5997
|
+
});
|
|
5998
|
+
if (existingSet.has(key)) issues.set(i, { message: `Cannot add offers to existing group ${offer.group}` });
|
|
5999
|
+
}
|
|
6000
|
+
return issues;
|
|
6001
|
+
});
|
|
5253
6002
|
|
|
5254
6003
|
//#endregion
|
|
5255
6004
|
//#region src/gatekeeper/morphoRules.ts
|
|
5256
6005
|
const morphoRules = (parameters) => {
|
|
5257
|
-
const { chains, chainId } = parameters;
|
|
6006
|
+
const { chains, chainId, db } = parameters;
|
|
6007
|
+
const requestChain = chains.find((c) => c.id === chainId);
|
|
6008
|
+
const config = requestChain ? configs[requestChain.name] : void 0;
|
|
5258
6009
|
const assetsByChainId = {};
|
|
5259
6010
|
const collateralAssetsByChainId = {};
|
|
5260
6011
|
const oraclesByChainId = {};
|
|
5261
6012
|
for (const chain of chains) {
|
|
5262
6013
|
assetsByChainId[chain.id] = assets[chain.id.toString()] ?? [];
|
|
5263
6014
|
collateralAssetsByChainId[chain.id] = collateralAssets[chain.id.toString()] ?? [];
|
|
5264
|
-
oraclesByChainId[chain.id] = oracles[chain.id.toString()] ?? [];
|
|
6015
|
+
oraclesByChainId[chain.id] = oracles$1[chain.id.toString()] ?? [];
|
|
5265
6016
|
}
|
|
5266
|
-
|
|
6017
|
+
const rules = [
|
|
5267
6018
|
sameMaker(),
|
|
5268
6019
|
amountMutualExclusivity(),
|
|
6020
|
+
groupConsistency(),
|
|
6021
|
+
...config?.minDuration != null ? [minDuration({ minSeconds: config.minDuration })] : [],
|
|
5269
6022
|
maturity({ maturities: [MaturityType.EndOfWeek, MaturityType.EndOfNextWeek] }),
|
|
5270
6023
|
callback({
|
|
5271
6024
|
callbacks: [Type$1.BuyWithEmptyCallback, Type$1.SellWithEmptyCallback],
|
|
@@ -5275,6 +6028,7 @@ const morphoRules = (parameters) => {
|
|
|
5275
6028
|
assetsByChainId,
|
|
5276
6029
|
chainId
|
|
5277
6030
|
}),
|
|
6031
|
+
maxCollaterals({ max: 128 }),
|
|
5278
6032
|
collateralToken({
|
|
5279
6033
|
collateralAssetsByChainId,
|
|
5280
6034
|
chainId
|
|
@@ -5284,6 +6038,11 @@ const morphoRules = (parameters) => {
|
|
|
5284
6038
|
chainId
|
|
5285
6039
|
})
|
|
5286
6040
|
];
|
|
6041
|
+
if (db) rules.push(groupImmutability({
|
|
6042
|
+
db,
|
|
6043
|
+
chainId
|
|
6044
|
+
}));
|
|
6045
|
+
return rules;
|
|
5287
6046
|
};
|
|
5288
6047
|
|
|
5289
6048
|
//#endregion
|
|
@@ -5409,16 +6168,13 @@ async function* streamOffers(config, parameters) {
|
|
|
5409
6168
|
};
|
|
5410
6169
|
}
|
|
5411
6170
|
var WalletAccountNotSetError = class extends BaseError {
|
|
6171
|
+
name = "Mempool.WalletAccountNotSetError";
|
|
5412
6172
|
constructor() {
|
|
5413
6173
|
super("Wallet account is not set.");
|
|
5414
|
-
_defineProperty(this, "name", "Mempool.WalletAccountNotSetError");
|
|
5415
6174
|
}
|
|
5416
6175
|
};
|
|
5417
6176
|
var ViemClientError = class extends BaseError {
|
|
5418
|
-
|
|
5419
|
-
super(..._args);
|
|
5420
|
-
_defineProperty(this, "name", "Mempool.ViemClientError");
|
|
5421
|
-
}
|
|
6177
|
+
name = "Mempool.ViemClientError";
|
|
5422
6178
|
};
|
|
5423
6179
|
const resolveSignatureDomain = (config, chainId) => {
|
|
5424
6180
|
const chain = config.client.chain;
|
|
@@ -5430,9 +6186,9 @@ const resolveSignatureDomain = (config, chainId) => {
|
|
|
5430
6186
|
};
|
|
5431
6187
|
};
|
|
5432
6188
|
var MissingMorphoAddressError = class extends BaseError {
|
|
6189
|
+
name = "Mempool.MissingMorphoAddressError";
|
|
5433
6190
|
constructor() {
|
|
5434
6191
|
super("Morpho address is required to verify root signatures (zero address is invalid).");
|
|
5435
|
-
_defineProperty(this, "name", "Mempool.MissingMorphoAddressError");
|
|
5436
6192
|
}
|
|
5437
6193
|
};
|
|
5438
6194
|
|
|
@@ -5446,158 +6202,6 @@ function connect(parameters) {
|
|
|
5446
6202
|
return from(parameters);
|
|
5447
6203
|
}
|
|
5448
6204
|
|
|
5449
|
-
//#endregion
|
|
5450
|
-
//#region src/utils/retry.ts
|
|
5451
|
-
const retry = async (fn, attempts = 3, delayMs = 50) => {
|
|
5452
|
-
let lastErr;
|
|
5453
|
-
for (let i = 0; i < attempts; i++) try {
|
|
5454
|
-
return await fn();
|
|
5455
|
-
} catch (err) {
|
|
5456
|
-
lastErr = err;
|
|
5457
|
-
if (i < attempts - 1) await new Promise((r) => setTimeout(r, delayMs));
|
|
5458
|
-
}
|
|
5459
|
-
throw lastErr;
|
|
5460
|
-
};
|
|
5461
|
-
|
|
5462
|
-
//#endregion
|
|
5463
|
-
//#region src/utils/batchMulticall.ts
|
|
5464
|
-
/**
|
|
5465
|
-
* Helper function to execute multicall in batches with retry logic.
|
|
5466
|
-
* Abstracts the common pattern of batching calls, retrying, and collecting results.
|
|
5467
|
-
*
|
|
5468
|
-
* @param parameters - Configuration for batched multicall
|
|
5469
|
-
* @returns Promise resolving to flattened array of results
|
|
5470
|
-
*/
|
|
5471
|
-
async function batchMulticall(parameters) {
|
|
5472
|
-
const { client, calls, batchSize, retryAttempts, retryDelayMs, blockNumber } = parameters;
|
|
5473
|
-
const results = [];
|
|
5474
|
-
for (const callsBatch of batch$1(calls, batchSize)) {
|
|
5475
|
-
const batchResults = await retry(() => multicall(client, {
|
|
5476
|
-
allowFailure: false,
|
|
5477
|
-
contracts: callsBatch,
|
|
5478
|
-
...blockNumber ? { blockNumber } : {}
|
|
5479
|
-
}), retryAttempts, retryDelayMs);
|
|
5480
|
-
results.push(...batchResults);
|
|
5481
|
-
}
|
|
5482
|
-
return results;
|
|
5483
|
-
}
|
|
5484
|
-
|
|
5485
|
-
//#endregion
|
|
5486
|
-
//#region src/utils/Group.ts
|
|
5487
|
-
var Group_exports = /* @__PURE__ */ __exportAll({ fromNumber: () => fromNumber });
|
|
5488
|
-
/**
|
|
5489
|
-
* Creates a bytes32 group identifier from a number.
|
|
5490
|
-
* @param n - A non-negative integer.
|
|
5491
|
-
* @throws {Error} If n is negative or not an integer.
|
|
5492
|
-
*/
|
|
5493
|
-
const fromNumber = (n) => {
|
|
5494
|
-
if (!Number.isInteger(n)) throw new Error(`Group.fromNumber: expected integer, got ${n}`);
|
|
5495
|
-
if (n < 0) throw new Error(`Group.fromNumber: expected non-negative, got ${n}`);
|
|
5496
|
-
return pad(`0x${n.toString(16)}`, { size: 32 });
|
|
5497
|
-
};
|
|
5498
|
-
|
|
5499
|
-
//#endregion
|
|
5500
|
-
//#region src/utils/lazy.ts
|
|
5501
|
-
/**
|
|
5502
|
-
* Transform a polling function into an async generator.
|
|
5503
|
-
* @param fn - The polling function to transform.
|
|
5504
|
-
* @returns An async generator.
|
|
5505
|
-
*/
|
|
5506
|
-
function lazy(pollFn) {
|
|
5507
|
-
return () => (async function* () {
|
|
5508
|
-
let active = true;
|
|
5509
|
-
let resolveNext = null;
|
|
5510
|
-
const queue = [];
|
|
5511
|
-
const wait = () => new Promise((resolve) => {
|
|
5512
|
-
resolveNext = resolve;
|
|
5513
|
-
});
|
|
5514
|
-
const emit = (item) => {
|
|
5515
|
-
queue.push(item);
|
|
5516
|
-
resolveNext?.();
|
|
5517
|
-
resolveNext = null;
|
|
5518
|
-
};
|
|
5519
|
-
let unpoll = null;
|
|
5520
|
-
const stop = () => {
|
|
5521
|
-
active = false;
|
|
5522
|
-
unpoll?.();
|
|
5523
|
-
resolveNext?.();
|
|
5524
|
-
resolveNext = null;
|
|
5525
|
-
};
|
|
5526
|
-
unpoll = pollFn(emit, { stop });
|
|
5527
|
-
try {
|
|
5528
|
-
while (active) {
|
|
5529
|
-
if (queue.length === 0) await wait();
|
|
5530
|
-
while (queue.length > 0 && active) yield queue.shift();
|
|
5531
|
-
}
|
|
5532
|
-
} finally {
|
|
5533
|
-
stop();
|
|
5534
|
-
}
|
|
5535
|
-
})();
|
|
5536
|
-
}
|
|
5537
|
-
|
|
5538
|
-
//#endregion
|
|
5539
|
-
//#region src/utils/wait.ts
|
|
5540
|
-
async function wait(time) {
|
|
5541
|
-
return new Promise((res) => setTimeout(res, time));
|
|
5542
|
-
}
|
|
5543
|
-
|
|
5544
|
-
//#endregion
|
|
5545
|
-
//#region src/utils/poll.ts
|
|
5546
|
-
/**
|
|
5547
|
-
* Polls a function at a specified interval.
|
|
5548
|
-
* Inspired by https://github.com/wevm/viem/blob/845994d20275d08ff892018e237a4b599eeefb6a/src/utils/poll.ts
|
|
5549
|
-
*/
|
|
5550
|
-
function poll(fn, { interval }) {
|
|
5551
|
-
let active = true;
|
|
5552
|
-
const unwatch = () => active = false;
|
|
5553
|
-
const watch = async () => {
|
|
5554
|
-
while (active) {
|
|
5555
|
-
const delay = await interval();
|
|
5556
|
-
if (!active) break;
|
|
5557
|
-
await wait(delay);
|
|
5558
|
-
if (!active) break;
|
|
5559
|
-
await fn({ unpoll: unwatch });
|
|
5560
|
-
}
|
|
5561
|
-
};
|
|
5562
|
-
watch();
|
|
5563
|
-
return unwatch;
|
|
5564
|
-
}
|
|
5565
|
-
|
|
5566
|
-
//#endregion
|
|
5567
|
-
//#region src/utils/time.ts
|
|
5568
|
-
var time_exports = /* @__PURE__ */ __exportAll({
|
|
5569
|
-
max: () => max,
|
|
5570
|
-
now: () => now
|
|
5571
|
-
});
|
|
5572
|
-
function now() {
|
|
5573
|
-
return Math.floor(Date.now() / 1e3);
|
|
5574
|
-
}
|
|
5575
|
-
function max() {
|
|
5576
|
-
return 0x77e772392b600000;
|
|
5577
|
-
}
|
|
5578
|
-
|
|
5579
|
-
//#endregion
|
|
5580
|
-
//#region src/utils/index.ts
|
|
5581
|
-
var utils_exports = /* @__PURE__ */ __exportAll({
|
|
5582
|
-
BaseError: () => BaseError,
|
|
5583
|
-
Group: () => Group_exports,
|
|
5584
|
-
Random: () => Random_exports,
|
|
5585
|
-
ReorgError: () => ReorgError,
|
|
5586
|
-
Time: () => time_exports,
|
|
5587
|
-
atMostOneNonZero: () => atMostOneNonZero,
|
|
5588
|
-
batch: () => batch$1,
|
|
5589
|
-
batchMulticall: () => batchMulticall,
|
|
5590
|
-
fromSnakeCase: () => fromSnakeCase$3,
|
|
5591
|
-
lazy: () => lazy,
|
|
5592
|
-
max: () => max$1,
|
|
5593
|
-
min: () => min,
|
|
5594
|
-
poll: () => poll,
|
|
5595
|
-
retry: () => retry,
|
|
5596
|
-
stringifyBigint: () => stringifyBigint,
|
|
5597
|
-
toSnakeCase: () => toSnakeCase$1,
|
|
5598
|
-
wait: () => wait
|
|
5599
|
-
});
|
|
5600
|
-
|
|
5601
6205
|
//#endregion
|
|
5602
6206
|
export { Abi_exports as Abi, BrandTypeId, Callback_exports as Callback, Chain_exports as Chain, ChainRegistry_exports as ChainRegistry, Collateral_exports as Collateral, ERC4626_exports as ERC4626, Errors_exports as Errors, Format_exports as Format, Gatekeeper_exports as Gatekeeper, Client_exports as GatekeeperClient, Id_exports as Id, LLTV_exports as LLTV, Liquidity_exports as Liquidity, Maturity_exports as Maturity, MempoolClient_exports as Mempool, Obligation_exports as Obligation, Offer_exports as Offer, Oracle_exports as Oracle, Position_exports as Position, Quote_exports as Quote, Schema_exports as RouterApi, Client_exports$1 as RouterClient, Rules_exports as Rules, Tick_exports as Tick, time_exports as Time, TradingFee_exports as TradingFee, Transfer_exports as Transfer, Tree_exports as Tree, utils_exports as Utils, Gate_exports as Validation, morphoRules };
|
|
5603
6207
|
//# sourceMappingURL=index.browser.mjs.map
|