@morpho-dev/router 0.12.0 → 0.12.1
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 +799 -316
- package/dist/drizzle/migrations/0050_contract-sync-v1.16.sql +305 -0
- package/dist/drizzle/migrations/meta/0050_snapshot.json +2035 -0
- package/dist/drizzle/migrations/meta/_journal.json +7 -0
- package/dist/evm/bytecode/morpho.txt +1 -1
- package/dist/index.browser.d.mts +60 -47
- package/dist/index.browser.d.mts.map +1 -1
- package/dist/index.browser.mjs +127 -77
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.d.mts +130 -90
- package/dist/index.node.d.mts.map +1 -1
- package/dist/index.node.mjs +733 -314
- package/dist/index.node.mjs.map +1 -1
- package/dist/{server-D4xxddev.js → server-DNFuP89-.js} +1 -1
- package/dist/server.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -211,7 +211,7 @@ function startActiveSpan(tracer, name, fn) {
|
|
|
211
211
|
//#endregion
|
|
212
212
|
//#region package.json
|
|
213
213
|
var name = "@morpho-dev/router";
|
|
214
|
-
var version = "0.12.
|
|
214
|
+
var version = "0.12.1";
|
|
215
215
|
var description = "Router package for Morpho protocol";
|
|
216
216
|
|
|
217
217
|
//#endregion
|
|
@@ -341,8 +341,8 @@ const chains$1 = {
|
|
|
341
341
|
name: "base",
|
|
342
342
|
custom: {
|
|
343
343
|
morpho: {
|
|
344
|
-
address: "
|
|
345
|
-
blockCreated:
|
|
344
|
+
address: "0x26378861d9c740fe86e7472752aef5b1a783c60b",
|
|
345
|
+
blockCreated: 43606117
|
|
346
346
|
},
|
|
347
347
|
morphoBlue: {
|
|
348
348
|
address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
|
|
@@ -371,8 +371,8 @@ const chains$1 = {
|
|
|
371
371
|
name: "ethereum-virtual-testnet",
|
|
372
372
|
custom: {
|
|
373
373
|
morpho: {
|
|
374
|
-
address: "
|
|
375
|
-
blockCreated:
|
|
374
|
+
address: "0x94c576ee728ee290116ee65c0d1e9fed4a1b5041",
|
|
375
|
+
blockCreated: 23244323
|
|
376
376
|
},
|
|
377
377
|
morphoBlue: {
|
|
378
378
|
address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
|
|
@@ -807,7 +807,7 @@ async function startDetached(config, logPath) {
|
|
|
807
807
|
}
|
|
808
808
|
async function startInProcess(config, logPath) {
|
|
809
809
|
fs.closeSync(fs.openSync(logPath, "w"));
|
|
810
|
-
const { startServer: startProolServer } = await import("./server-
|
|
810
|
+
const { startServer: startProolServer } = await import("./server-DNFuP89-.js");
|
|
811
811
|
const stop = await startProolServer(config);
|
|
812
812
|
return {
|
|
813
813
|
process: {
|
|
@@ -929,6 +929,7 @@ const transformAddress = (val, ctx) => {
|
|
|
929
929
|
});
|
|
930
930
|
return z$2.NEVER;
|
|
931
931
|
};
|
|
932
|
+
const AddressSchema = z$2.string().transform(transformAddress);
|
|
932
933
|
|
|
933
934
|
//#endregion
|
|
934
935
|
//#region src/chain/state.ts
|
|
@@ -1767,14 +1768,8 @@ const isEmptyCallback = (offer) => offer.callback.data === "0x";
|
|
|
1767
1768
|
|
|
1768
1769
|
//#endregion
|
|
1769
1770
|
//#region src/core/Maturity.ts
|
|
1770
|
-
const
|
|
1771
|
-
|
|
1772
|
-
from$15(maturity);
|
|
1773
|
-
return true;
|
|
1774
|
-
} catch (_e) {
|
|
1775
|
-
return false;
|
|
1776
|
-
}
|
|
1777
|
-
}, { error: (issue) => {
|
|
1771
|
+
const MAX_TIMESTAMP_SECONDS = 999999999999;
|
|
1772
|
+
const MaturitySchema = z$2.number().int().max(MAX_TIMESTAMP_SECONDS).refine(isAt15UTC, { error: (issue) => {
|
|
1778
1773
|
try {
|
|
1779
1774
|
return `The maturity is set to ${/* @__PURE__ */ new Date(issue.input * 1e3)}. It must be at 15:00:00 UTC.`;
|
|
1780
1775
|
} catch (_) {
|
|
@@ -1809,7 +1804,7 @@ function from$15(ts) {
|
|
|
1809
1804
|
if (ts in MaturityOptions) return MaturityOptions[ts]();
|
|
1810
1805
|
throw new InvalidOptionError$1(ts);
|
|
1811
1806
|
}
|
|
1812
|
-
if (typeof ts === "number" && ts >
|
|
1807
|
+
if (typeof ts === "number" && ts > MAX_TIMESTAMP_SECONDS) throw new InvalidFormatError();
|
|
1813
1808
|
if (!isAt15UTC(ts)) throw new InvalidDateError(ts);
|
|
1814
1809
|
return ts;
|
|
1815
1810
|
}
|
|
@@ -1903,7 +1898,6 @@ const assets = {
|
|
|
1903
1898
|
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
|
|
1904
1899
|
"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb",
|
|
1905
1900
|
"0x4200000000000000000000000000000000000006",
|
|
1906
|
-
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
|
|
1907
1901
|
"0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
|
|
1908
1902
|
"0xc1CBa3fCea344f92D9239c08C0568f6F2F0ee452",
|
|
1909
1903
|
"0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42"
|
|
@@ -2055,7 +2049,7 @@ const MorphoV2 = parseAbi([
|
|
|
2055
2049
|
"function obligationCreated(bytes32 id) view returns (bool)",
|
|
2056
2050
|
"function obligationState(bytes32 id) view returns (uint128 totalUnits, uint256 withdrawable, uint128 lossIndex, bool created)",
|
|
2057
2051
|
"function owner() view returns (address)",
|
|
2058
|
-
"function repay((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256
|
|
2052
|
+
"function repay((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 units, address onBehalf)",
|
|
2059
2053
|
"function session(address user) view returns (bytes32)",
|
|
2060
2054
|
"function setConsumed(bytes32 group, uint256 amount, address onBehalf)",
|
|
2061
2055
|
"function setDefaultTradingFee(address loanToken, uint256 index, uint256 newTradingFee)",
|
|
@@ -2070,7 +2064,7 @@ const MorphoV2 = parseAbi([
|
|
|
2070
2064
|
"function shuffleSession(address onBehalf)",
|
|
2071
2065
|
"function slash(bytes32 id, address user)",
|
|
2072
2066
|
"function supplyCollateral((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 collateralIndex, uint256 assets, address onBehalf)",
|
|
2073
|
-
"function take(uint256
|
|
2067
|
+
"function take(uint256 units, address taker, address takerCallback, bytes takerCallbackData, address receiverIfTakerIsSeller, ((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, bool buy, address maker, uint256 maxUnits, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData, address receiverIfMakerIsSeller, bool exitOnly) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof) returns (uint256, uint256, uint256)",
|
|
2074
2068
|
"function toId((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation) view returns (bytes32)",
|
|
2075
2069
|
"function toObligation(bytes32 id) view returns ((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold))",
|
|
2076
2070
|
"function totalUnits(bytes32 id) view returns (uint256)",
|
|
@@ -2078,14 +2072,14 @@ const MorphoV2 = parseAbi([
|
|
|
2078
2072
|
"function tradingFee(bytes32 id, uint256 timeToMaturity) view returns (uint256)",
|
|
2079
2073
|
"function tradingFeeRecipient() view returns (address)",
|
|
2080
2074
|
"function userLossIndex(bytes32 id, address user) view returns (uint128)",
|
|
2081
|
-
"function withdraw((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256
|
|
2075
|
+
"function withdraw((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 units, address onBehalf, address receiver)",
|
|
2082
2076
|
"function withdrawCollateral((address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation, uint256 collateralIndex, uint256 assets, address onBehalf, address receiver)",
|
|
2083
2077
|
"function withdrawable(bytes32 id) view returns (uint256)",
|
|
2084
2078
|
"event Constructor(address indexed owner)",
|
|
2085
2079
|
"event FlashLoan(address indexed caller, address indexed token, uint256 assets)",
|
|
2086
2080
|
"event Liquidate(address indexed caller, bytes32 indexed id_, uint256 collateralIndex, uint256 seizedAssets, uint256 repaidUnits, address indexed borrower, uint256 badDebt, uint256 latestLossIndex)",
|
|
2087
2081
|
"event ObligationCreated(bytes32 indexed id_, (address loanToken, (address token, uint256 lltv, uint256 maxLif, address oracle)[] collaterals, uint256 maturity, uint256 rcfThreshold) obligation)",
|
|
2088
|
-
"event Repay(address indexed caller, bytes32 indexed id_, uint256
|
|
2082
|
+
"event Repay(address indexed caller, bytes32 indexed id_, uint256 units, address indexed onBehalf)",
|
|
2089
2083
|
"event SetConsumed(address indexed caller, address indexed onBehalf, bytes32 indexed group, uint256 amount)",
|
|
2090
2084
|
"event SetDefaultTradingFee(address indexed loanToken, uint256 indexed index, uint256 newTradingFee)",
|
|
2091
2085
|
"event SetFeeSetter(address indexed feeSetter)",
|
|
@@ -2099,8 +2093,8 @@ const MorphoV2 = parseAbi([
|
|
|
2099
2093
|
"event ShuffleSession(address indexed caller, address indexed onBehalf, bytes32 session)",
|
|
2100
2094
|
"event Slash(address caller, bytes32 indexed id_, address indexed user, uint256 credit, uint256 latestLossIndex)",
|
|
2101
2095
|
"event SupplyCollateral(address caller, bytes32 indexed id_, address indexed collateral, uint256 assets, address indexed onBehalf)",
|
|
2102
|
-
"event Take(address caller, bytes32 indexed id_, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256
|
|
2103
|
-
"event Withdraw(address caller, bytes32 indexed id_, uint256
|
|
2096
|
+
"event Take(address caller, bytes32 indexed id_, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256 units, address sellerReceiver, bytes32 group, uint256 consumed, uint256 totalUnits)",
|
|
2097
|
+
"event Withdraw(address caller, bytes32 indexed id_, uint256 units, address indexed onBehalf, address indexed receiver)",
|
|
2104
2098
|
"event WithdrawCollateral(address caller, bytes32 indexed id_, address indexed collateral, uint256 assets, address indexed onBehalf, address receiver)"
|
|
2105
2099
|
]);
|
|
2106
2100
|
|
|
@@ -2276,10 +2270,10 @@ const abi$1 = [
|
|
|
2276
2270
|
}
|
|
2277
2271
|
];
|
|
2278
2272
|
const CollateralSchema = z$2.object({
|
|
2279
|
-
asset:
|
|
2280
|
-
oracle:
|
|
2273
|
+
asset: AddressSchema,
|
|
2274
|
+
oracle: AddressSchema,
|
|
2281
2275
|
lltv: LLTVSchema,
|
|
2282
|
-
maxLif: z$2.bigint({ coerce: true }).min(0n)
|
|
2276
|
+
maxLif: z$2.bigint({ coerce: true }).min(0n)
|
|
2283
2277
|
});
|
|
2284
2278
|
const CollateralsSchema = z$2.array(CollateralSchema).min(1, { message: "At least one collateral is required" }).refine((collaterals) => {
|
|
2285
2279
|
for (let i = 1; i < collaterals.length; i++) if (collaterals[i - 1].asset.toLowerCase() > collaterals[i].asset.toLowerCase()) return false;
|
|
@@ -2297,7 +2291,7 @@ const from$13 = (parameters) => {
|
|
|
2297
2291
|
return {
|
|
2298
2292
|
asset: parameters.asset.toLowerCase(),
|
|
2299
2293
|
lltv: from$14(parameters.lltv),
|
|
2300
|
-
maxLif: parameters.maxLif
|
|
2294
|
+
maxLif: parameters.maxLif,
|
|
2301
2295
|
oracle: parameters.oracle.toLowerCase()
|
|
2302
2296
|
};
|
|
2303
2297
|
};
|
|
@@ -2388,7 +2382,7 @@ function stringifyBigint(value) {
|
|
|
2388
2382
|
//#endregion
|
|
2389
2383
|
//#region src/core/Obligation.ts
|
|
2390
2384
|
const ObligationSchema = z$2.object({
|
|
2391
|
-
loanToken:
|
|
2385
|
+
loanToken: AddressSchema,
|
|
2392
2386
|
collaterals: CollateralsSchema,
|
|
2393
2387
|
maturity: MaturitySchema,
|
|
2394
2388
|
rcfThreshold: z$2.bigint({ coerce: true }).min(0n)
|
|
@@ -2431,7 +2425,8 @@ const tupleAbi = [{
|
|
|
2431
2425
|
* Collateral.from({
|
|
2432
2426
|
* asset: privateKeyToAccount(generatePrivateKey()).address,
|
|
2433
2427
|
* oracle: privateKeyToAccount(generatePrivateKey()).address,
|
|
2434
|
-
* lltv: 0.965
|
|
2428
|
+
* lltv: 0.965,
|
|
2429
|
+
* maxLif: 0n,
|
|
2435
2430
|
* }),
|
|
2436
2431
|
* ],
|
|
2437
2432
|
* maturity: Maturity.from("end_of_next_quarter"),
|
|
@@ -2481,7 +2476,7 @@ function key(parameters) {
|
|
|
2481
2476
|
parameters.collaterals.map((c) => ({
|
|
2482
2477
|
token: c.asset.toLowerCase(),
|
|
2483
2478
|
lltv: c.lltv,
|
|
2484
|
-
maxLif: c.maxLif
|
|
2479
|
+
maxLif: c.maxLif,
|
|
2485
2480
|
oracle: c.oracle.toLowerCase()
|
|
2486
2481
|
})),
|
|
2487
2482
|
BigInt(parameters.maturity),
|
|
@@ -2533,7 +2528,7 @@ function creationCode(parameters) {
|
|
|
2533
2528
|
collaterals: parameters.obligation.collaterals.map((collateral) => ({
|
|
2534
2529
|
token: collateral.asset.toLowerCase(),
|
|
2535
2530
|
lltv: collateral.lltv,
|
|
2536
|
-
maxLif: collateral.maxLif
|
|
2531
|
+
maxLif: collateral.maxLif,
|
|
2537
2532
|
oracle: collateral.oracle.toLowerCase()
|
|
2538
2533
|
})),
|
|
2539
2534
|
maturity: BigInt(parameters.obligation.maturity),
|
|
@@ -2567,8 +2562,8 @@ let Status = /* @__PURE__ */ function(Status) {
|
|
|
2567
2562
|
}({});
|
|
2568
2563
|
const OfferSchema = () => {
|
|
2569
2564
|
return z$2.object({
|
|
2570
|
-
maker:
|
|
2571
|
-
|
|
2565
|
+
maker: AddressSchema,
|
|
2566
|
+
maxUnits: z$2.bigint({ coerce: true }).min(0n).max(maxUint256).optional().default(0n),
|
|
2572
2567
|
tick: z$2.coerce.number().int().min(0).max(990),
|
|
2573
2568
|
maturity: MaturitySchema,
|
|
2574
2569
|
rcfThreshold: z$2.bigint({ coerce: true }).min(0n).max(maxUint256),
|
|
@@ -2585,13 +2580,13 @@ const OfferSchema = () => {
|
|
|
2585
2580
|
z$2.bigint()
|
|
2586
2581
|
]).optional().default("0x0000000000000000000000000000000000000000000000000000000000000000").transform(transformBytes32),
|
|
2587
2582
|
buy: z$2.boolean(),
|
|
2588
|
-
loanToken:
|
|
2583
|
+
loanToken: AddressSchema,
|
|
2589
2584
|
collaterals: CollateralsSchema,
|
|
2590
2585
|
callback: z$2.object({
|
|
2591
|
-
address:
|
|
2586
|
+
address: AddressSchema,
|
|
2592
2587
|
data: z$2.string().transform(transformHex)
|
|
2593
2588
|
}),
|
|
2594
|
-
receiverIfMakerIsSeller:
|
|
2589
|
+
receiverIfMakerIsSeller: AddressSchema,
|
|
2595
2590
|
exitOnly: z$2.boolean().optional().default(false)
|
|
2596
2591
|
}).refine((data) => data.start < data.expiry, {
|
|
2597
2592
|
message: "start must be before expiry",
|
|
@@ -2644,7 +2639,7 @@ function toSnakeCase(offer) {
|
|
|
2644
2639
|
*/
|
|
2645
2640
|
const serialize = (offer) => ({
|
|
2646
2641
|
maker: offer.maker,
|
|
2647
|
-
|
|
2642
|
+
maxUnits: offer.maxUnits.toString(),
|
|
2648
2643
|
tick: offer.tick,
|
|
2649
2644
|
maturity: Number(offer.maturity),
|
|
2650
2645
|
rcfThreshold: offer.rcfThreshold.toString(),
|
|
@@ -2702,7 +2697,7 @@ function random(config) {
|
|
|
2702
2697
|
const loanTokenDecimals = config?.assetsDecimals?.[loanToken] ?? 18;
|
|
2703
2698
|
const unit = BigInt(10) ** BigInt(loanTokenDecimals);
|
|
2704
2699
|
const amountBase = BigInt(100 + int(999901));
|
|
2705
|
-
const
|
|
2700
|
+
const maxUnitsScaled = config?.maxUnits ?? amountBase * unit;
|
|
2706
2701
|
const emptyCallback = {
|
|
2707
2702
|
address: zeroAddress,
|
|
2708
2703
|
data: "0x"
|
|
@@ -2710,7 +2705,7 @@ function random(config) {
|
|
|
2710
2705
|
const maker = config?.maker ?? address();
|
|
2711
2706
|
return from$11({
|
|
2712
2707
|
maker,
|
|
2713
|
-
|
|
2708
|
+
maxUnits: maxUnitsScaled,
|
|
2714
2709
|
tick,
|
|
2715
2710
|
maturity,
|
|
2716
2711
|
rcfThreshold: config?.rcfThreshold ?? 0n,
|
|
@@ -2764,7 +2759,7 @@ function hash$1(offer) {
|
|
|
2764
2759
|
* Obligation obligation; // nested tuple
|
|
2765
2760
|
* bool buy;
|
|
2766
2761
|
* address maker;
|
|
2767
|
-
* uint256
|
|
2762
|
+
* uint256 maxUnits;
|
|
2768
2763
|
* uint256 start;
|
|
2769
2764
|
* uint256 expiry;
|
|
2770
2765
|
* uint256 tick;
|
|
@@ -2830,7 +2825,7 @@ const OfferAbi = [{
|
|
|
2830
2825
|
type: "address"
|
|
2831
2826
|
},
|
|
2832
2827
|
{
|
|
2833
|
-
name: "
|
|
2828
|
+
name: "maxUnits",
|
|
2834
2829
|
type: "uint256"
|
|
2835
2830
|
},
|
|
2836
2831
|
{
|
|
@@ -2878,7 +2873,7 @@ function encode(offer) {
|
|
|
2878
2873
|
collaterals: offer.collaterals.map((c) => ({
|
|
2879
2874
|
token: c.asset,
|
|
2880
2875
|
lltv: c.lltv,
|
|
2881
|
-
maxLif: c.maxLif
|
|
2876
|
+
maxLif: c.maxLif,
|
|
2882
2877
|
oracle: c.oracle
|
|
2883
2878
|
})),
|
|
2884
2879
|
maturity: BigInt(offer.maturity),
|
|
@@ -2886,7 +2881,7 @@ function encode(offer) {
|
|
|
2886
2881
|
},
|
|
2887
2882
|
buy: offer.buy,
|
|
2888
2883
|
maker: offer.maker,
|
|
2889
|
-
|
|
2884
|
+
maxUnits: offer.maxUnits,
|
|
2890
2885
|
start: BigInt(offer.start),
|
|
2891
2886
|
expiry: BigInt(offer.expiry),
|
|
2892
2887
|
tick: BigInt(offer.tick),
|
|
@@ -2948,7 +2943,7 @@ const takeEvent = {
|
|
|
2948
2943
|
internalType: "uint256"
|
|
2949
2944
|
},
|
|
2950
2945
|
{
|
|
2951
|
-
name: "
|
|
2946
|
+
name: "units",
|
|
2952
2947
|
type: "uint256",
|
|
2953
2948
|
indexed: false,
|
|
2954
2949
|
internalType: "uint256"
|
|
@@ -3034,7 +3029,7 @@ const repayEvent = {
|
|
|
3034
3029
|
internalType: "bytes32"
|
|
3035
3030
|
},
|
|
3036
3031
|
{
|
|
3037
|
-
name: "
|
|
3032
|
+
name: "units",
|
|
3038
3033
|
type: "uint256",
|
|
3039
3034
|
indexed: false,
|
|
3040
3035
|
internalType: "uint256"
|
|
@@ -3315,24 +3310,79 @@ function assertTick(tick) {
|
|
|
3315
3310
|
if (!Number.isInteger(tick) || tick < 0 || tick > TICK_RANGE) throw new InvalidTickError(tick);
|
|
3316
3311
|
}
|
|
3317
3312
|
/**
|
|
3318
|
-
* Converts
|
|
3319
|
-
*
|
|
3313
|
+
* Converts units into maker-side assets using the raw tick price surface.
|
|
3314
|
+
* This is the public forward conversion used by the router for lot sizing and other maker-facing capacity math.
|
|
3315
|
+
* - `buy = true` -> `floor(units * price / WAD)`
|
|
3316
|
+
* - `buy = false` -> `ceil(units * price / WAD)`
|
|
3317
|
+
* @param units - The units to convert.
|
|
3320
3318
|
* @param tick - The offer tick.
|
|
3321
|
-
* @
|
|
3319
|
+
* @param buy - Whether the maker side of the offer is buy (`true`) or sell (`false`).
|
|
3320
|
+
* @returns The equivalent amount in maker-side assets.
|
|
3322
3321
|
*/
|
|
3323
|
-
function
|
|
3324
|
-
|
|
3322
|
+
function unitsToAssets(units, tick, buy) {
|
|
3323
|
+
const price = tickToPrice(tick);
|
|
3324
|
+
return buy ? unitsToFloorAssets(units, price) : unitsToCeilAssets(units, price);
|
|
3325
3325
|
}
|
|
3326
3326
|
/**
|
|
3327
|
-
* Converts
|
|
3328
|
-
*
|
|
3327
|
+
* Converts a maker-side asset cap into a safe units cap using the raw tick price.
|
|
3328
|
+
* Buy offers use the max-safe inverse of `floor(units * price / WAD)`.
|
|
3329
|
+
* Sell offers use the max-safe inverse of `ceil(units * price / WAD)`.
|
|
3330
|
+
* The result is clamped to the remaining offer size because the asset cap may have been rounded before inversion.
|
|
3331
|
+
* Zero integer asset caps can still admit positive units on floor-rounded sub-WAD buy ticks, and tick=0 keeps the
|
|
3332
|
+
* whole remaining interval safe because the raw maker-asset surface stays at zero.
|
|
3333
|
+
* @param assets - The integer maker-side asset cap.
|
|
3329
3334
|
* @param tick - The offer tick.
|
|
3330
|
-
* @
|
|
3335
|
+
* @param buy - Whether the maker side of the offer is buy (`true`) or sell (`false`).
|
|
3336
|
+
* @param remainingUnits - The maximum units still available on the offer.
|
|
3337
|
+
* @returns The greatest safe units amount under the maker-side raw-price surface.
|
|
3331
3338
|
*/
|
|
3332
|
-
function
|
|
3339
|
+
function assetsToUnits(assets, tick, buy, remainingUnits) {
|
|
3340
|
+
if (remainingUnits <= 0n) return 0n;
|
|
3341
|
+
if (assets < 0n) return 0n;
|
|
3333
3342
|
const price = tickToPrice(tick);
|
|
3334
|
-
if (price === 0n) return
|
|
3335
|
-
|
|
3343
|
+
if (price === 0n) return remainingUnits;
|
|
3344
|
+
const units = buy ? floorAssetsToUnits(assets, price) : ceilAssetsToUnits(assets, price);
|
|
3345
|
+
return units > remainingUnits ? remainingUnits : units;
|
|
3346
|
+
}
|
|
3347
|
+
/**
|
|
3348
|
+
* Forward conversion for raw-price floor surfaces.
|
|
3349
|
+
* This matches buy-side maker assets and the legacy floor-only helper.
|
|
3350
|
+
* @param units - The units to convert.
|
|
3351
|
+
* @param price - The raw tick price.
|
|
3352
|
+
* @returns The floor-rounded maker-side assets.
|
|
3353
|
+
*/
|
|
3354
|
+
function unitsToFloorAssets(units, price) {
|
|
3355
|
+
return units * price / WAD$1;
|
|
3356
|
+
}
|
|
3357
|
+
/**
|
|
3358
|
+
* Forward conversion for raw-price ceil surfaces.
|
|
3359
|
+
* This matches sell-side maker assets, where the maker receives `sellerAssets` rounded up onchain.
|
|
3360
|
+
* @param units - The units to convert.
|
|
3361
|
+
* @param price - The raw tick price.
|
|
3362
|
+
* @returns The ceil-rounded maker-side assets.
|
|
3363
|
+
*/
|
|
3364
|
+
function unitsToCeilAssets(units, price) {
|
|
3365
|
+
return (units * price + WAD$1 - 1n) / WAD$1;
|
|
3366
|
+
}
|
|
3367
|
+
/**
|
|
3368
|
+
* Max-safe inverse for floor surfaces.
|
|
3369
|
+
* It returns the greatest units value whose floor-rounded maker assets stay within `assets`.
|
|
3370
|
+
* @param assets - The maker-side asset cap.
|
|
3371
|
+
* @param price - The raw tick price.
|
|
3372
|
+
* @returns The greatest safe obligation-units amount under `floor(units * price / WAD) <= assets`.
|
|
3373
|
+
*/
|
|
3374
|
+
function floorAssetsToUnits(assets, price) {
|
|
3375
|
+
return ((assets + 1n) * WAD$1 - 1n) / price;
|
|
3376
|
+
}
|
|
3377
|
+
/**
|
|
3378
|
+
* Max-safe inverse for ceil surfaces.
|
|
3379
|
+
* It returns the greatest units value whose ceil-rounded maker assets stay within `assets`.
|
|
3380
|
+
* @param assets - The maker-side asset cap.
|
|
3381
|
+
* @param price - The raw tick price.
|
|
3382
|
+
* @returns The greatest safe obligation-units amount under `ceil(units * price / WAD) <= assets`.
|
|
3383
|
+
*/
|
|
3384
|
+
function ceilAssetsToUnits(assets, price) {
|
|
3385
|
+
return assets * WAD$1 / price;
|
|
3336
3386
|
}
|
|
3337
3387
|
var InvalidTickError = class extends BaseError {
|
|
3338
3388
|
name = "Tick.InvalidTickError";
|
|
@@ -3814,7 +3864,7 @@ const DEFAULT_BATCH_SIZE = 1500;
|
|
|
3814
3864
|
|
|
3815
3865
|
//#endregion
|
|
3816
3866
|
//#region src/database/drizzle/VERSION.ts
|
|
3817
|
-
const VERSION = "router_v1.
|
|
3867
|
+
const VERSION = "router_v1.16";
|
|
3818
3868
|
|
|
3819
3869
|
//#endregion
|
|
3820
3870
|
//#region src/database/drizzle/schema.ts
|
|
@@ -3962,7 +4012,7 @@ const oracles = s.table(EnumTableName.ORACLES, {
|
|
|
3962
4012
|
const offers = s.table(EnumTableName.OFFERS, {
|
|
3963
4013
|
hash: varchar("hash", { length: 66 }).notNull(),
|
|
3964
4014
|
obligationId: varchar("obligation_id", { length: 66 }).notNull().references(() => obligationIdKeys.obligationId, { onDelete: "cascade" }),
|
|
3965
|
-
|
|
4015
|
+
maxUnits: numeric("max_units", {
|
|
3966
4016
|
precision: 78,
|
|
3967
4017
|
scale: 0
|
|
3968
4018
|
}).notNull().default("0"),
|
|
@@ -4003,8 +4053,8 @@ const offers = s.table(EnumTableName.OFFERS, {
|
|
|
4003
4053
|
index("offers_obligation_side_tick_idx").on(table.obligationId, table.buy, table.tick),
|
|
4004
4054
|
index("offers_obligation_active_tick_idx").on(table.obligationId, table.buy, table.expiry, table.maturity, table.start, table.tick),
|
|
4005
4055
|
index("offers_group_maker_idx").on(table.groupMaker, table.hash, table.obligationId),
|
|
4006
|
-
index("offers_group_winner_expr_idx").on(table.groupChainId, table.groupMaker, table.group, table.obligationId, table.buy, sql`(CASE WHEN "buy" THEN -"tick" ELSE "tick" END)`, table.blockNumber, sql`"
|
|
4007
|
-
index("offers_book_winners_covering_idx").on(table.obligationId, table.buy, table.groupChainId, table.groupMaker, table.group, sql`(CASE WHEN "buy" THEN -"tick" ELSE "tick" END)`, table.blockNumber, sql`"
|
|
4056
|
+
index("offers_group_winner_expr_idx").on(table.groupChainId, table.groupMaker, table.group, table.obligationId, table.buy, sql`(CASE WHEN "buy" THEN -"tick" ELSE "tick" END)`, table.blockNumber, sql`"max_units" DESC`, table.hash),
|
|
4057
|
+
index("offers_book_winners_covering_idx").on(table.obligationId, table.buy, table.groupChainId, table.groupMaker, table.group, sql`(CASE WHEN "buy" THEN -"tick" ELSE "tick" END)`, table.blockNumber, sql`"max_units" DESC`, table.hash)
|
|
4008
4058
|
]);
|
|
4009
4059
|
const offersCallbacks = s.table(EnumTableName.OFFERS_CALLBACKS, {
|
|
4010
4060
|
offerHash: varchar("offer_hash", { length: 66 }).notNull(),
|
|
@@ -4312,7 +4362,7 @@ function compositeKey(g) {
|
|
|
4312
4362
|
function create$30(db) {
|
|
4313
4363
|
return {
|
|
4314
4364
|
create: async (groups$3) => {
|
|
4315
|
-
if (groups$3.length === 0) return;
|
|
4365
|
+
if (groups$3.length === 0) return 0;
|
|
4316
4366
|
const rows = groups$3.map((group) => ({
|
|
4317
4367
|
chainId: group.chainId,
|
|
4318
4368
|
maker: group.maker.toLowerCase(),
|
|
@@ -4320,7 +4370,12 @@ function create$30(db) {
|
|
|
4320
4370
|
consumed: (group.consumed ?? 0n).toString(),
|
|
4321
4371
|
blockNumber: group.blockNumber
|
|
4322
4372
|
}));
|
|
4323
|
-
|
|
4373
|
+
let insertedCount = 0;
|
|
4374
|
+
for (const batch of batch$1(rows, DEFAULT_BATCH_SIZE)) {
|
|
4375
|
+
const inserted = await db.insert(groups).values(batch).onConflictDoNothing().returning();
|
|
4376
|
+
insertedCount += inserted.length;
|
|
4377
|
+
}
|
|
4378
|
+
return insertedCount;
|
|
4324
4379
|
},
|
|
4325
4380
|
exists: async (groups$4) => {
|
|
4326
4381
|
if (groups$4.length === 0) return [];
|
|
@@ -4417,16 +4472,16 @@ const maxCollaterals = ({ max }) => single("max_collaterals", `Validates that an
|
|
|
4417
4472
|
if (offer.collaterals.length > max) return { message: `Offer has ${offer.collaterals.length} collaterals, exceeding the maximum of ${max}` };
|
|
4418
4473
|
});
|
|
4419
4474
|
/**
|
|
4420
|
-
* A validation rule that checks if the offer's
|
|
4475
|
+
* A validation rule that checks if the offer's maxUnits is non-zero.
|
|
4421
4476
|
* The contract requires a positive amount; this rule rejects early.
|
|
4422
4477
|
* @returns The issue that was found. If the offer is valid, this will be undefined.
|
|
4423
4478
|
*/
|
|
4424
|
-
const amountNonZero = () => single("amount_non_zero", "Validates that
|
|
4425
|
-
if (offer.
|
|
4479
|
+
const amountNonZero = () => single("amount_non_zero", "Validates that maxUnits is non-zero", (offer) => {
|
|
4480
|
+
if (offer.maxUnits === 0n) return { message: "maxUnits must be non-zero" };
|
|
4426
4481
|
});
|
|
4427
4482
|
/**
|
|
4428
4483
|
* A batch validation rule that ensures all offers within the same group are consistent.
|
|
4429
|
-
* All offers sharing the same group must have the same loan token,
|
|
4484
|
+
* All offers sharing the same group must have the same loan token, maxUnits,
|
|
4430
4485
|
* and side (buy/sell). The contract tracks consumed per group and requires these to match.
|
|
4431
4486
|
*/
|
|
4432
4487
|
const groupConsistency = () => batch("group_consistency", "Validates that all offers in a group have the same loan token, obligation amounts, and side", (offers) => {
|
|
@@ -4443,13 +4498,13 @@ const groupConsistency = () => batch("group_consistency", "Validates that all of
|
|
|
4443
4498
|
if (indices.length <= 1) continue;
|
|
4444
4499
|
const reference = offers[indices[0]];
|
|
4445
4500
|
const refLoanToken = reference.loanToken.toLowerCase();
|
|
4446
|
-
const refUnits = reference.
|
|
4501
|
+
const refUnits = reference.maxUnits;
|
|
4447
4502
|
const refBuy = reference.buy;
|
|
4448
4503
|
for (let j = 1; j < indices.length; j++) {
|
|
4449
4504
|
const idx = indices[j];
|
|
4450
4505
|
const offer = offers[idx];
|
|
4451
4506
|
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}` });
|
|
4452
|
-
else if (offer.
|
|
4507
|
+
else if (offer.maxUnits !== refUnits) issues.set(idx, { message: `All offers in a group must have the same maxUnits. Expected ${refUnits}, got ${offer.maxUnits}` });
|
|
4453
4508
|
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"}` });
|
|
4454
4509
|
}
|
|
4455
4510
|
}
|
|
@@ -4666,7 +4721,7 @@ function from$5(level) {
|
|
|
4666
4721
|
return {
|
|
4667
4722
|
tick: level.tick,
|
|
4668
4723
|
price: price.toString(),
|
|
4669
|
-
|
|
4724
|
+
max_units: level.maxUnits.toString(),
|
|
4670
4725
|
count: level.count
|
|
4671
4726
|
};
|
|
4672
4727
|
}
|
|
@@ -4775,7 +4830,7 @@ function from$3(input) {
|
|
|
4775
4830
|
},
|
|
4776
4831
|
buy: input.buy,
|
|
4777
4832
|
maker: input.maker,
|
|
4778
|
-
|
|
4833
|
+
max_units: input.maxUnits.toString(),
|
|
4779
4834
|
start: input.start,
|
|
4780
4835
|
expiry: input.expiry,
|
|
4781
4836
|
tick: input.tick,
|
|
@@ -4934,7 +4989,7 @@ const offerExample = {
|
|
|
4934
4989
|
},
|
|
4935
4990
|
buy: false,
|
|
4936
4991
|
maker: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
4937
|
-
|
|
4992
|
+
max_units: "369216000000000000000000",
|
|
4938
4993
|
start: 1761922790,
|
|
4939
4994
|
expiry: 1761922799,
|
|
4940
4995
|
tick: 495,
|
|
@@ -4977,7 +5032,7 @@ const missingCollectorExample = {
|
|
|
4977
5032
|
};
|
|
4978
5033
|
const validateOfferExample = {
|
|
4979
5034
|
maker: "0x7b093658BE7f90B63D7c359e8f408e503c2D9401",
|
|
4980
|
-
|
|
5035
|
+
max_units: "369216000000000000000000",
|
|
4981
5036
|
tick: 495,
|
|
4982
5037
|
maturity: 1761922799,
|
|
4983
5038
|
rcf_threshold: "0",
|
|
@@ -5131,8 +5186,8 @@ __decorate([ApiProperty({
|
|
|
5131
5186
|
})], OfferDataResponse.prototype, "maker", void 0);
|
|
5132
5187
|
__decorate([ApiProperty({
|
|
5133
5188
|
type: "string",
|
|
5134
|
-
example: offerExample.offer.
|
|
5135
|
-
})], OfferDataResponse.prototype, "
|
|
5189
|
+
example: offerExample.offer.max_units
|
|
5190
|
+
})], OfferDataResponse.prototype, "max_units", void 0);
|
|
5136
5191
|
__decorate([ApiProperty({
|
|
5137
5192
|
type: "number",
|
|
5138
5193
|
example: offerExample.offer.start
|
|
@@ -5386,9 +5441,9 @@ __decorate([ApiProperty({
|
|
|
5386
5441
|
})], ValidateOfferRequest.prototype, "maker", void 0);
|
|
5387
5442
|
__decorate([ApiProperty({
|
|
5388
5443
|
type: "string",
|
|
5389
|
-
example: validateOfferExample.
|
|
5444
|
+
example: validateOfferExample.max_units,
|
|
5390
5445
|
required: false
|
|
5391
|
-
})], ValidateOfferRequest.prototype, "
|
|
5446
|
+
})], ValidateOfferRequest.prototype, "max_units", void 0);
|
|
5392
5447
|
__decorate([ApiProperty({
|
|
5393
5448
|
type: "number",
|
|
5394
5449
|
example: validateOfferExample.tick,
|
|
@@ -5522,7 +5577,7 @@ __decorate([ApiProperty({
|
|
|
5522
5577
|
__decorate([ApiProperty({
|
|
5523
5578
|
type: "string",
|
|
5524
5579
|
example: "369216000000000000000000"
|
|
5525
|
-
})], BookLevelResponse.prototype, "
|
|
5580
|
+
})], BookLevelResponse.prototype, "max_units", void 0);
|
|
5526
5581
|
__decorate([ApiProperty({
|
|
5527
5582
|
type: "number",
|
|
5528
5583
|
example: 5
|
|
@@ -7530,11 +7585,11 @@ function offerBalanceTerm(balance, price, lltv) {
|
|
|
7530
7585
|
* @param lotLower - Lot lower bound (in assets).
|
|
7531
7586
|
* @param lotUpper - Lot upper bound (in assets).
|
|
7532
7587
|
* @param consumed - Group consumed amount (in obligation units).
|
|
7533
|
-
* @param
|
|
7588
|
+
* @param maxUnits - Offer obligation units.
|
|
7534
7589
|
*/
|
|
7535
|
-
function lotBalance(offerBalance, offset, positionConsumed, lotLower, lotUpper, consumed,
|
|
7590
|
+
function lotBalance(offerBalance, offset, positionConsumed, lotLower, lotUpper, consumed, maxUnits) {
|
|
7536
7591
|
const lotSize = sql`(COALESCE(${lotUpper}::numeric, 0) - COALESCE(${lotLower}::numeric, 0))`;
|
|
7537
|
-
return sql`GREATEST(0, LEAST(COALESCE(${offerBalance}, 0) + COALESCE(${offset}, 0) + COALESCE(${positionConsumed}, 0) - COALESCE(${lotLower}::numeric, 0), ${lotSize} - ${sql`CASE WHEN ${
|
|
7592
|
+
return sql`GREATEST(0, LEAST(COALESCE(${offerBalance}, 0) + COALESCE(${offset}, 0) + COALESCE(${positionConsumed}, 0) - COALESCE(${lotLower}::numeric, 0), ${lotSize} - ${sql`CASE WHEN ${maxUnits}::numeric > 0 THEN COALESCE(${consumed}::numeric, 0) * ${lotSize} / ${maxUnits}::numeric ELSE 0 END`}))`;
|
|
7538
7593
|
}
|
|
7539
7594
|
/**
|
|
7540
7595
|
* Callback contribution: amount contributed by one callback in loan terms.
|
|
@@ -7546,17 +7601,23 @@ function contribution(lotBalance, lotLower) {
|
|
|
7546
7601
|
return sql`CASE WHEN ${lotLower} IS NULL THEN 0 ELSE ${lotBalance} END`;
|
|
7547
7602
|
}
|
|
7548
7603
|
/**
|
|
7549
|
-
* Takeable amount in assets.
|
|
7550
|
-
*
|
|
7551
|
-
*
|
|
7552
|
-
*
|
|
7604
|
+
* Takeable amount in maker-side assets.
|
|
7605
|
+
* Buy offers use the floor maker-asset surface for remaining obligation units.
|
|
7606
|
+
* Sell offers use the ceil maker-asset surface for remaining obligation units.
|
|
7607
|
+
* The result is then compared with available (already in assets from lot balance).
|
|
7608
|
+
* @param maxUnits - Offer obligation units.
|
|
7553
7609
|
* @param consumed - Group consumed amount (in obligation units).
|
|
7554
7610
|
* @param available - Total available from callbacks/positions (in assets).
|
|
7555
7611
|
* @param price - Tick price (from tick_prices CTE).
|
|
7612
|
+
* @param buy - Offer side (`true` for buy, `false` for sell).
|
|
7556
7613
|
*/
|
|
7557
|
-
function takeable(
|
|
7614
|
+
function takeable(maxUnits, consumed, available, price, buy) {
|
|
7558
7615
|
const WAD_SQL = sql`(10::numeric ^ 18)`;
|
|
7559
|
-
|
|
7616
|
+
const remainingUnits = sql`GREATEST(COALESCE(${maxUnits}::numeric, 0) - COALESCE(${consumed}::numeric, 0), 0)`;
|
|
7617
|
+
return sql`GREATEST(0, LEAST(${sql`CASE WHEN ${buy}
|
|
7618
|
+
THEN TRUNC(${remainingUnits} * COALESCE(${price}::numeric, 0) / ${WAD_SQL})
|
|
7619
|
+
ELSE CEIL(${remainingUnits} * COALESCE(${price}::numeric, 0) / ${WAD_SQL})
|
|
7620
|
+
END`}, ${available}))`;
|
|
7560
7621
|
}
|
|
7561
7622
|
/** Precomputed tick→price lookup (all 991 ticks). */
|
|
7562
7623
|
const TICK_PRICES = Array.from({ length: TICK_RANGE + 1 }, (_, i) => [i, tickToPrice(i).toString()]);
|
|
@@ -7588,7 +7649,7 @@ function offerAvailabilityCTEs(params) {
|
|
|
7588
7649
|
return sql`
|
|
7589
7650
|
, group_winners AS (
|
|
7590
7651
|
SELECT DISTINCT ON (o.group_chain_id, o.group_maker, o.group_group, o.obligation_id, o.buy)
|
|
7591
|
-
o.group_chain_id, o.group_maker, o.group_group, o.obligation_id, o.buy, o.
|
|
7652
|
+
o.group_chain_id, o.group_maker, o.group_group, o.obligation_id, o.buy, o.max_units
|
|
7592
7653
|
FROM ${offers} o
|
|
7593
7654
|
LEFT JOIN ${validations} v
|
|
7594
7655
|
ON v.offer_hash = o.hash
|
|
@@ -7605,7 +7666,7 @@ function offerAvailabilityCTEs(params) {
|
|
|
7605
7666
|
ORDER BY
|
|
7606
7667
|
o.group_chain_id, o.group_maker, o.group_group, o.obligation_id, o.buy,
|
|
7607
7668
|
CASE WHEN o.buy THEN -o.tick ELSE o.tick END ASC,
|
|
7608
|
-
o.block_number ASC, o.
|
|
7669
|
+
o.block_number ASC, o.max_units DESC, o.hash ASC
|
|
7609
7670
|
),
|
|
7610
7671
|
relevant_positions AS (
|
|
7611
7672
|
SELECT DISTINCT c.position_chain_id, c.position_contract, c.position_user
|
|
@@ -7630,8 +7691,8 @@ function offerAvailabilityCTEs(params) {
|
|
|
7630
7691
|
COALESCE(
|
|
7631
7692
|
SUM(
|
|
7632
7693
|
CASE
|
|
7633
|
-
WHEN wo.
|
|
7634
|
-
THEN COALESCE(g.consumed::numeric, 0) * (l.upper::numeric - l.lower::numeric) / wo.
|
|
7694
|
+
WHEN wo.max_units::numeric > 0
|
|
7695
|
+
THEN COALESCE(g.consumed::numeric, 0) * (l.upper::numeric - l.lower::numeric) / wo.max_units::numeric
|
|
7635
7696
|
ELSE 0
|
|
7636
7697
|
END
|
|
7637
7698
|
) OVER (
|
|
@@ -7678,14 +7739,14 @@ function offerAvailabilityCTEs(params) {
|
|
|
7678
7739
|
src.obligation_id,
|
|
7679
7740
|
src.group_group,
|
|
7680
7741
|
src.consumed,
|
|
7681
|
-
src.
|
|
7742
|
+
src.max_units,
|
|
7682
7743
|
c.id AS callback_id,
|
|
7683
7744
|
c.position_chain_id,
|
|
7684
7745
|
c.position_contract,
|
|
7685
7746
|
c.position_user,
|
|
7686
7747
|
l.lower AS lot_lower,
|
|
7687
7748
|
l.upper AS lot_upper,
|
|
7688
|
-
${lotBalance(sql`vb.offer_balance`, sql`pos_offsets.total_offset`, sql`pc.consumed`, sql`l.lower`, sql`l.upper`, sql`src.consumed`, sql`src.
|
|
7749
|
+
${lotBalance(sql`vb.offer_balance`, sql`pos_offsets.total_offset`, sql`pc.consumed`, sql`l.lower`, sql`l.upper`, sql`src.consumed`, sql`src.max_units`)} AS lot_balance
|
|
7689
7750
|
FROM ${source} src
|
|
7690
7751
|
LEFT JOIN ${offersCallbacks} oc
|
|
7691
7752
|
ON oc.offer_hash = src.hash
|
|
@@ -7753,7 +7814,7 @@ function offerTakeabilityCTEs(params) {
|
|
|
7753
7814
|
offer_takeable AS (
|
|
7754
7815
|
SELECT src.hash, src.obligation_id,
|
|
7755
7816
|
COALESCE(oa.available, 0) AS available,
|
|
7756
|
-
${takeable(sql`src.
|
|
7817
|
+
${takeable(sql`src.max_units`, sql`src.consumed`, sql`COALESCE(oa.available, 0)`, sql`tp.price`, sql`src.buy`)} AS takeable
|
|
7757
7818
|
FROM ${source} src
|
|
7758
7819
|
LEFT JOIN offer_available oa ON oa.hash = src.hash AND oa.obligation_id = src.obligation_id
|
|
7759
7820
|
LEFT JOIN tick_prices tp ON tp.tick = src.tick
|
|
@@ -7892,7 +7953,7 @@ function create$27(config) {
|
|
|
7892
7953
|
const db = config.db;
|
|
7893
7954
|
const logger = getLogger();
|
|
7894
7955
|
const getOffers = async (parameters) => {
|
|
7895
|
-
const { side, obligationId, cursor: cursorString } = parameters;
|
|
7956
|
+
const { side, obligationId, cursor: cursorString, requirePositiveTakeableAssets = false } = parameters;
|
|
7896
7957
|
const requestedLimit = parameters.limit ?? DEFAULT_LIMIT$4;
|
|
7897
7958
|
const priceSortDirection = side === "sell" ? "asc" : "desc";
|
|
7898
7959
|
const inputCursor = Cursor.decode(cursorString, logger);
|
|
@@ -7913,7 +7974,8 @@ function create$27(config) {
|
|
|
7913
7974
|
now,
|
|
7914
7975
|
priceSortDirection,
|
|
7915
7976
|
cursor: inputCursor,
|
|
7916
|
-
limit: Math.min(requestedLimit, MAX_TOTAL_OFFERS - previouslyReturned)
|
|
7977
|
+
limit: Math.min(requestedLimit, MAX_TOTAL_OFFERS - previouslyReturned),
|
|
7978
|
+
requirePositiveTakeableAssets
|
|
7917
7979
|
});
|
|
7918
7980
|
const lastReturnedOffer = rows[rows.length - 1];
|
|
7919
7981
|
const newTotalReturned = previouslyReturned + rows.length;
|
|
@@ -7945,16 +8007,16 @@ function create$27(config) {
|
|
|
7945
8007
|
for (const row of rows) {
|
|
7946
8008
|
const existing = tickMap.get(row.tick);
|
|
7947
8009
|
if (existing) {
|
|
7948
|
-
existing.
|
|
8010
|
+
existing.maxUnits += row.takeable;
|
|
7949
8011
|
existing.count += 1;
|
|
7950
8012
|
} else tickMap.set(row.tick, {
|
|
7951
|
-
|
|
8013
|
+
maxUnits: row.takeable,
|
|
7952
8014
|
count: 1
|
|
7953
8015
|
});
|
|
7954
8016
|
}
|
|
7955
8017
|
const levels = Array.from(tickMap.entries()).map(([tick, level]) => ({
|
|
7956
8018
|
tick,
|
|
7957
|
-
|
|
8019
|
+
maxUnits: level.maxUnits,
|
|
7958
8020
|
count: level.count
|
|
7959
8021
|
}));
|
|
7960
8022
|
levels.sort((a, b) => tickSortDirection === "asc" ? a.tick - b.tick : b.tick - a.tick);
|
|
@@ -7971,15 +8033,15 @@ function create$27(config) {
|
|
|
7971
8033
|
}
|
|
7972
8034
|
/** Get offers with computed takeable based on lot balance. */
|
|
7973
8035
|
async function _getOffers(db, params) {
|
|
7974
|
-
const { obligationId, side, now, priceSortDirection, cursor, limit } = params;
|
|
8036
|
+
const { obligationId, side, now, priceSortDirection, cursor, limit, requirePositiveTakeableAssets } = params;
|
|
7975
8037
|
const raw = await db.execute(sql`
|
|
7976
8038
|
WITH collats AS MATERIALIZED (
|
|
7977
8039
|
SELECT oia.obligation_id,
|
|
7978
8040
|
COALESCE(jsonb_agg(jsonb_build_object(
|
|
7979
8041
|
'asset', oc.asset,
|
|
7980
8042
|
'oracle', oc.oracle_address,
|
|
7981
|
-
'lltv', oc.lltv,
|
|
7982
|
-
'maxLif', oc.max_lif
|
|
8043
|
+
'lltv', oc.lltv::text,
|
|
8044
|
+
'maxLif', oc.max_lif::text
|
|
7983
8045
|
) ORDER BY oc.asset), '[]'::jsonb) AS collaterals
|
|
7984
8046
|
FROM ${obligationIdKeys} oia
|
|
7985
8047
|
JOIN ${obligationCollateralsV2} oc
|
|
@@ -8004,7 +8066,7 @@ async function _getOffers(db, params) {
|
|
|
8004
8066
|
AND (s.code IS NULL OR s.code = ${Status.VALID})
|
|
8005
8067
|
ORDER BY
|
|
8006
8068
|
o.group_chain_id, o.group_maker, o."group_group",
|
|
8007
|
-
CASE WHEN o.buy THEN -o.tick ELSE o.tick END ASC, o.block_number ASC, o.
|
|
8069
|
+
CASE WHEN o.buy THEN -o.tick ELSE o.tick END ASC, o.block_number ASC, o.max_units DESC, o.hash ASC
|
|
8008
8070
|
),
|
|
8009
8071
|
enriched AS (
|
|
8010
8072
|
SELECT
|
|
@@ -8013,7 +8075,7 @@ async function _getOffers(db, params) {
|
|
|
8013
8075
|
CASE WHEN ${priceSortDirection === "asc" ? sql`TRUE` : sql`FALSE`}
|
|
8014
8076
|
THEN w.tick ELSE -w.tick END AS tick_norm,
|
|
8015
8077
|
w.block_number AS block_norm,
|
|
8016
|
-
-w.
|
|
8078
|
+
-w.max_units AS max_units_norm,
|
|
8017
8079
|
w.hash AS hash_norm
|
|
8018
8080
|
FROM winners w
|
|
8019
8081
|
JOIN ${groups} g
|
|
@@ -8034,24 +8096,34 @@ async function _getOffers(db, params) {
|
|
|
8034
8096
|
SELECT e.*, COALESCE(ot.available, 0) AS available, ot.takeable
|
|
8035
8097
|
FROM enriched e
|
|
8036
8098
|
JOIN offer_takeable ot ON ot.hash = e.hash AND ot.obligation_id = e.obligation_id
|
|
8037
|
-
WHERE
|
|
8099
|
+
WHERE (
|
|
8100
|
+
ot.takeable > 0
|
|
8101
|
+
OR (
|
|
8102
|
+
COALESCE(e.max_units::numeric, 0) > COALESCE(e.consumed::numeric, 0)
|
|
8103
|
+
AND (
|
|
8104
|
+
e.tick = 0
|
|
8105
|
+
OR (e.buy AND e.tick < ${TICK_RANGE})
|
|
8106
|
+
)
|
|
8107
|
+
)
|
|
8108
|
+
)
|
|
8109
|
+
${requirePositiveTakeableAssets ? sql`AND TRUNC(COALESCE(ot.takeable, 0)::numeric) > 0` : sql``}
|
|
8038
8110
|
${cursor != null ? sql`
|
|
8039
|
-
AND (e.tick_norm, e.block_norm, e.
|
|
8111
|
+
AND (e.tick_norm, e.block_norm, e.max_units_norm, e.hash_norm)
|
|
8040
8112
|
> (
|
|
8041
8113
|
CASE WHEN ${priceSortDirection === "asc" ? sql`TRUE` : sql`FALSE`}
|
|
8042
8114
|
THEN ${cursor.tick}::integer ELSE -${cursor.tick}::integer END,
|
|
8043
8115
|
${cursor.blockNumber},
|
|
8044
|
-
-${cursor.
|
|
8116
|
+
-${cursor.maxUnits}::numeric,
|
|
8045
8117
|
${cursor.hash}
|
|
8046
8118
|
)` : sql``}
|
|
8047
|
-
ORDER BY e.tick ${priceSortDirection === "asc" ? sql`ASC` : sql`DESC`}, e.block_number ASC, e.
|
|
8119
|
+
ORDER BY e.tick ${priceSortDirection === "asc" ? sql`ASC` : sql`DESC`}, e.block_number ASC, e.max_units DESC, e.hash ASC
|
|
8048
8120
|
LIMIT ${limit}
|
|
8049
8121
|
)
|
|
8050
8122
|
SELECT
|
|
8051
8123
|
p.hash,
|
|
8052
8124
|
p.obligation_id,
|
|
8053
8125
|
p.group_maker,
|
|
8054
|
-
p.
|
|
8126
|
+
p.max_units,
|
|
8055
8127
|
p.consumed,
|
|
8056
8128
|
p.tick,
|
|
8057
8129
|
p.maturity,
|
|
@@ -8081,17 +8153,20 @@ async function _getOffers(db, params) {
|
|
|
8081
8153
|
ORDER BY
|
|
8082
8154
|
p.tick ${priceSortDirection === "asc" ? sql`ASC` : sql`DESC`},
|
|
8083
8155
|
p.block_number ASC,
|
|
8084
|
-
p.
|
|
8156
|
+
p.max_units DESC,
|
|
8085
8157
|
p.hash ASC;
|
|
8086
8158
|
`);
|
|
8087
8159
|
return {
|
|
8088
8160
|
rows: raw.rows.map((row) => {
|
|
8089
8161
|
const receiverIfMakerIsSeller = (row.receiver_if_maker_is_seller ?? row.group_maker).toLowerCase();
|
|
8162
|
+
const maxUnits = BigInt(row.max_units ?? 0);
|
|
8163
|
+
const consumed = BigInt(row.consumed ?? 0);
|
|
8164
|
+
const remainingUnits = maxUnits > consumed ? maxUnits - consumed : 0n;
|
|
8090
8165
|
return {
|
|
8091
8166
|
hash: row.hash,
|
|
8092
8167
|
obligationId: row.obligation_id,
|
|
8093
8168
|
maker: row.group_maker,
|
|
8094
|
-
|
|
8169
|
+
maxUnits,
|
|
8095
8170
|
tick: row.tick,
|
|
8096
8171
|
maturity: row.maturity,
|
|
8097
8172
|
expiry: row.expiry,
|
|
@@ -8106,7 +8181,7 @@ async function _getOffers(db, params) {
|
|
|
8106
8181
|
asset: c.asset,
|
|
8107
8182
|
oracle: c.oracle,
|
|
8108
8183
|
lltv: BigInt(c.lltv),
|
|
8109
|
-
maxLif: BigInt(c.maxLif
|
|
8184
|
+
maxLif: BigInt(c.maxLif)
|
|
8110
8185
|
})),
|
|
8111
8186
|
callback: {
|
|
8112
8187
|
address: row.callback_address,
|
|
@@ -8115,9 +8190,9 @@ async function _getOffers(db, params) {
|
|
|
8115
8190
|
receiverIfMakerIsSeller,
|
|
8116
8191
|
exitOnly: row.exit_only,
|
|
8117
8192
|
blockNumber: row.block_number,
|
|
8118
|
-
consumed
|
|
8193
|
+
consumed,
|
|
8119
8194
|
available: BigInt(String(row.available ?? "0").split(".")[0] ?? "0"),
|
|
8120
|
-
takeable:
|
|
8195
|
+
takeable: assetsToUnits(BigInt(String(row.takeable).split(".")[0] ?? "0"), row.tick, row.buy, remainingUnits),
|
|
8121
8196
|
root: row.tree_root ? row.tree_root.toLowerCase() : void 0,
|
|
8122
8197
|
signature: row.root_signature ? row.root_signature.toLowerCase() : void 0,
|
|
8123
8198
|
proof: row.proof_nodes ? splitProofs(row.proof_nodes) : void 0
|
|
@@ -8133,7 +8208,7 @@ let Cursor;
|
|
|
8133
8208
|
side,
|
|
8134
8209
|
tick: row.tick,
|
|
8135
8210
|
blockNumber: row.blockNumber,
|
|
8136
|
-
|
|
8211
|
+
maxUnits: row.maxUnits.toString(),
|
|
8137
8212
|
hash: row.hash,
|
|
8138
8213
|
totalReturned,
|
|
8139
8214
|
now
|
|
@@ -8144,7 +8219,7 @@ let Cursor;
|
|
|
8144
8219
|
if (cursorString == null) return null;
|
|
8145
8220
|
try {
|
|
8146
8221
|
const v = JSON.parse(Buffer.from(cursorString, "base64url").toString("utf8"));
|
|
8147
|
-
if ((v?.side === "buy" || v?.side === "sell") && typeof v?.tick === "number" && Number.isInteger(v.tick) && typeof v?.blockNumber === "number" && Number.isInteger(v.blockNumber) && typeof v?.
|
|
8222
|
+
if ((v?.side === "buy" || v?.side === "sell") && typeof v?.tick === "number" && Number.isInteger(v.tick) && typeof v?.blockNumber === "number" && Number.isInteger(v.blockNumber) && typeof v?.maxUnits === "string" && /^-?\d+$/.test(v.maxUnits) && isHex(v?.hash) && typeof v?.totalReturned === "number" && Number.isInteger(v.totalReturned) && typeof v?.now === "number" && Number.isInteger(v.now)) return v;
|
|
8148
8223
|
throw new Error("Invalid cursor");
|
|
8149
8224
|
} catch {
|
|
8150
8225
|
logger.error({
|
|
@@ -8196,7 +8271,10 @@ let LevelCursor;
|
|
|
8196
8271
|
function create$26(db) {
|
|
8197
8272
|
return {
|
|
8198
8273
|
upsert: async (inputs) => {
|
|
8199
|
-
if (inputs.length === 0) return
|
|
8274
|
+
if (inputs.length === 0) return {
|
|
8275
|
+
callbacksInserted: 0,
|
|
8276
|
+
offersCallbacksInserted: 0
|
|
8277
|
+
};
|
|
8200
8278
|
const idCache = /* @__PURE__ */ new Map();
|
|
8201
8279
|
const seenCallbackIds = /* @__PURE__ */ new Set();
|
|
8202
8280
|
const callbacksRows = [];
|
|
@@ -8236,7 +8314,10 @@ function create$26(db) {
|
|
|
8236
8314
|
});
|
|
8237
8315
|
}
|
|
8238
8316
|
}
|
|
8239
|
-
if (offersCallbacksRows.length === 0) return
|
|
8317
|
+
if (offersCallbacksRows.length === 0) return {
|
|
8318
|
+
callbacksInserted: 0,
|
|
8319
|
+
offersCallbacksInserted: 0
|
|
8320
|
+
};
|
|
8240
8321
|
const offerHashes = [...new Set(offersCallbacksRows.map((r) => r.offerHash))];
|
|
8241
8322
|
const existingOffers = await db.select({
|
|
8242
8323
|
hash: offers.hash,
|
|
@@ -8244,10 +8325,25 @@ function create$26(db) {
|
|
|
8244
8325
|
}).from(offers).where(inArray(offers.hash, offerHashes));
|
|
8245
8326
|
const existingKeys = new Set(existingOffers.map((r) => `${String(r.hash).toLowerCase()}:${String(r.obligationId).toLowerCase()}`));
|
|
8246
8327
|
const filteredOffersCallbacksRows = offersCallbacksRows.filter((r) => existingKeys.has(`${r.offerHash}:${r.obligationId}`));
|
|
8247
|
-
if (filteredOffersCallbacksRows.length === 0) return
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8328
|
+
if (filteredOffersCallbacksRows.length === 0) return {
|
|
8329
|
+
callbacksInserted: 0,
|
|
8330
|
+
offersCallbacksInserted: 0
|
|
8331
|
+
};
|
|
8332
|
+
return await db.transaction(async (dbTx) => {
|
|
8333
|
+
let callbacksInserted = 0;
|
|
8334
|
+
for (const batch of batch$1(callbacksRows, DEFAULT_BATCH_SIZE)) {
|
|
8335
|
+
const inserted = await dbTx.insert(callbacks).values(batch).onConflictDoNothing().returning();
|
|
8336
|
+
callbacksInserted += inserted.length;
|
|
8337
|
+
}
|
|
8338
|
+
let offersCallbacksInserted = 0;
|
|
8339
|
+
for (const batch of batch$1(filteredOffersCallbacksRows, DEFAULT_BATCH_SIZE)) {
|
|
8340
|
+
const inserted = await dbTx.insert(offersCallbacks).values(batch).onConflictDoNothing().returning();
|
|
8341
|
+
offersCallbacksInserted += inserted.length;
|
|
8342
|
+
}
|
|
8343
|
+
return {
|
|
8344
|
+
callbacksInserted,
|
|
8345
|
+
offersCallbacksInserted
|
|
8346
|
+
};
|
|
8251
8347
|
});
|
|
8252
8348
|
},
|
|
8253
8349
|
delete: async ({ offers }) => {
|
|
@@ -8263,7 +8359,10 @@ function create$26(db) {
|
|
|
8263
8359
|
function create$25(db) {
|
|
8264
8360
|
return {
|
|
8265
8361
|
create: async (events) => {
|
|
8266
|
-
if (events.length === 0) return
|
|
8362
|
+
if (events.length === 0) return {
|
|
8363
|
+
groupsInserted: 0,
|
|
8364
|
+
consumedEventsInserted: 0
|
|
8365
|
+
};
|
|
8267
8366
|
const groups$2 = /* @__PURE__ */ new Map();
|
|
8268
8367
|
for (const event of events) {
|
|
8269
8368
|
const groupId = `${event.chainId}-${event.maker}-${event.group}`.toLowerCase();
|
|
@@ -8274,7 +8373,7 @@ function create$25(db) {
|
|
|
8274
8373
|
blockNumber: event.blockNumber
|
|
8275
8374
|
});
|
|
8276
8375
|
}
|
|
8277
|
-
await db.transaction(async (dbTx) => {
|
|
8376
|
+
return await db.transaction(async (dbTx) => {
|
|
8278
8377
|
const groupsRows = Array.from(groups$2.values()).map((group) => ({
|
|
8279
8378
|
chainId: group.chainId,
|
|
8280
8379
|
maker: group.maker.toLowerCase(),
|
|
@@ -8282,7 +8381,11 @@ function create$25(db) {
|
|
|
8282
8381
|
consumed: "0",
|
|
8283
8382
|
blockNumber: group.blockNumber
|
|
8284
8383
|
}));
|
|
8285
|
-
|
|
8384
|
+
let groupsInserted = 0;
|
|
8385
|
+
for (const batch of batch$1(groupsRows, DEFAULT_BATCH_SIZE)) {
|
|
8386
|
+
const inserted = await dbTx.insert(groups).values(batch).onConflictDoNothing().returning();
|
|
8387
|
+
groupsInserted += inserted.length;
|
|
8388
|
+
}
|
|
8286
8389
|
const eventsRows = events.map((event) => ({
|
|
8287
8390
|
eventId: event.id,
|
|
8288
8391
|
chainId: event.chainId,
|
|
@@ -8291,7 +8394,15 @@ function create$25(db) {
|
|
|
8291
8394
|
amount: event.amount.toString(),
|
|
8292
8395
|
blockNumber: event.blockNumber
|
|
8293
8396
|
}));
|
|
8294
|
-
|
|
8397
|
+
let consumedEventsInserted = 0;
|
|
8398
|
+
for (const batch of batch$1(eventsRows, DEFAULT_BATCH_SIZE)) {
|
|
8399
|
+
const inserted = await dbTx.insert(consumedEvents).values(batch).onConflictDoNothing().returning();
|
|
8400
|
+
consumedEventsInserted += inserted.length;
|
|
8401
|
+
}
|
|
8402
|
+
return {
|
|
8403
|
+
groupsInserted,
|
|
8404
|
+
consumedEventsInserted
|
|
8405
|
+
};
|
|
8295
8406
|
});
|
|
8296
8407
|
},
|
|
8297
8408
|
delete: async (parameters) => {
|
|
@@ -8324,7 +8435,10 @@ function create$24(db) {
|
|
|
8324
8435
|
}));
|
|
8325
8436
|
},
|
|
8326
8437
|
create: async (parameters) => {
|
|
8327
|
-
if (parameters.length === 0) return
|
|
8438
|
+
if (parameters.length === 0) return {
|
|
8439
|
+
lotsPositionsInserted: 0,
|
|
8440
|
+
lotsInserted: 0
|
|
8441
|
+
};
|
|
8328
8442
|
const lotsByKey = /* @__PURE__ */ new Map();
|
|
8329
8443
|
for (const offer of parameters) {
|
|
8330
8444
|
const key = `${offer.positionChainId}-${offer.positionContract}-${offer.positionUser}-${offer.group}-${offer.obligationId}`.toLowerCase();
|
|
@@ -8342,7 +8456,10 @@ function create$24(db) {
|
|
|
8342
8456
|
const groupKey = `${offer.positionChainId}-${offer.positionUser.toLowerCase()}-${offer.group.toLowerCase()}`;
|
|
8343
8457
|
if (!existingGroupKeys.has(groupKey)) lotsByKey.delete(key);
|
|
8344
8458
|
}
|
|
8345
|
-
if (lotsByKey.size === 0) return
|
|
8459
|
+
if (lotsByKey.size === 0) return {
|
|
8460
|
+
lotsPositionsInserted: 0,
|
|
8461
|
+
lotsInserted: 0
|
|
8462
|
+
};
|
|
8346
8463
|
const positionsByKey = /* @__PURE__ */ new Map();
|
|
8347
8464
|
for (const offer of lotsByKey.values()) {
|
|
8348
8465
|
const posKey = `${offer.positionChainId}-${offer.positionContract}-${offer.positionUser}`.toLowerCase();
|
|
@@ -8353,12 +8470,17 @@ function create$24(db) {
|
|
|
8353
8470
|
positionTypeId: offer.positionTypeId
|
|
8354
8471
|
});
|
|
8355
8472
|
}
|
|
8356
|
-
|
|
8473
|
+
let lotsPositionsInserted = 0;
|
|
8474
|
+
for (const row of positionsByKey.values()) {
|
|
8475
|
+
const inserted = await db.insert(lotsPositions).values(row).onConflictDoNothing().returning();
|
|
8476
|
+
lotsPositionsInserted += inserted.length;
|
|
8477
|
+
}
|
|
8478
|
+
let lotsInserted = 0;
|
|
8357
8479
|
for (const offer of lotsByKey.values()) if ((await db.select().from(lots).where(and(eq(lots.chainId, offer.positionChainId), eq(lots.contract, offer.positionContract.toLowerCase()), eq(lots.user, offer.positionUser.toLowerCase()), eq(lots.group, offer.group.toLowerCase()), eq(lots.obligationId, offer.obligationId.toLowerCase()))).limit(1)).length === 0) {
|
|
8358
8480
|
const maxUpperResult = await db.select({ maxUpper: sql`COALESCE(MAX(${lots.upper}::numeric), 0)` }).from(lots).where(and(eq(lots.chainId, offer.positionChainId), eq(lots.contract, offer.positionContract.toLowerCase()), eq(lots.user, offer.positionUser.toLowerCase()), eq(lots.obligationId, offer.obligationId.toLowerCase())));
|
|
8359
8481
|
const newLower = BigInt(maxUpperResult[0]?.maxUpper ?? "0");
|
|
8360
8482
|
const newUpper = newLower + offer.size;
|
|
8361
|
-
await db.insert(lots).values({
|
|
8483
|
+
const inserted = await db.insert(lots).values({
|
|
8362
8484
|
chainId: offer.positionChainId,
|
|
8363
8485
|
user: offer.positionUser.toLowerCase(),
|
|
8364
8486
|
contract: offer.positionContract.toLowerCase(),
|
|
@@ -8366,8 +8488,13 @@ function create$24(db) {
|
|
|
8366
8488
|
obligationId: offer.obligationId.toLowerCase(),
|
|
8367
8489
|
lower: newLower.toString(),
|
|
8368
8490
|
upper: newUpper.toString()
|
|
8369
|
-
});
|
|
8491
|
+
}).returning();
|
|
8492
|
+
lotsInserted += inserted.length;
|
|
8370
8493
|
}
|
|
8494
|
+
return {
|
|
8495
|
+
lotsPositionsInserted,
|
|
8496
|
+
lotsInserted
|
|
8497
|
+
};
|
|
8371
8498
|
}
|
|
8372
8499
|
};
|
|
8373
8500
|
}
|
|
@@ -8389,7 +8516,7 @@ function create$23(db) {
|
|
|
8389
8516
|
chainId: obligationIdKeys.chainId,
|
|
8390
8517
|
morphoV2: obligationIdKeys.morphoV2,
|
|
8391
8518
|
loanToken: obligations.loanToken,
|
|
8392
|
-
collaterals: sql`ARRAY_AGG(jsonb_build_object('asset', ${obligationCollateralsV2.asset}, 'oracle', ${obligationCollateralsV2.oracleAddress}, 'lltv', ${obligationCollateralsV2.lltv}, 'maxLif', ${obligationCollateralsV2.maxLif}))`.as("collaterals"),
|
|
8519
|
+
collaterals: sql`ARRAY_AGG(jsonb_build_object('asset', ${obligationCollateralsV2.asset}, 'oracle', ${obligationCollateralsV2.oracleAddress}, 'lltv', ${obligationCollateralsV2.lltv}::text, 'maxLif', ${obligationCollateralsV2.maxLif}::text))`.as("collaterals"),
|
|
8393
8520
|
maturity: obligations.maturity,
|
|
8394
8521
|
rcfThreshold: obligations.rcfThreshold
|
|
8395
8522
|
}).from(obligationIdKeys).innerJoin(obligations, eq(obligationIdKeys.obligationKey, obligations.obligationKey)).innerJoin(obligationCollateralsV2, eq(obligations.obligationKey, obligationCollateralsV2.obligationKey)).groupBy(obligationIdKeys.obligationId, obligationIdKeys.chainId, obligationIdKeys.morphoV2, obligations.loanToken, obligations.maturity, obligations.rcfThreshold).where(and(chainIds !== void 0 && chainIds.length > 0 ? inArray(obligationIdKeys.chainId, chainIds) : void 0, gte(obligations.maturity, now$3))).orderBy(asc(obligationIdKeys.obligationId))).map((row) => ({
|
|
@@ -8402,7 +8529,7 @@ function create$23(db) {
|
|
|
8402
8529
|
asset: collateral.asset,
|
|
8403
8530
|
oracle: collateral.oracle,
|
|
8404
8531
|
lltv: from$14(BigInt(collateral.lltv)),
|
|
8405
|
-
maxLif: BigInt(collateral.maxLif
|
|
8532
|
+
maxLif: BigInt(collateral.maxLif)
|
|
8406
8533
|
})),
|
|
8407
8534
|
maturity: row.maturity,
|
|
8408
8535
|
rcfThreshold: BigInt(row.rcfThreshold)
|
|
@@ -8410,7 +8537,11 @@ function create$23(db) {
|
|
|
8410
8537
|
}));
|
|
8411
8538
|
},
|
|
8412
8539
|
create: async (obligations$1) => {
|
|
8413
|
-
if (obligations$1.length === 0) return
|
|
8540
|
+
if (obligations$1.length === 0) return {
|
|
8541
|
+
obligationsInserted: 0,
|
|
8542
|
+
obligationIdKeysInserted: 0,
|
|
8543
|
+
obligationCollateralsInserted: 0
|
|
8544
|
+
};
|
|
8414
8545
|
const obligationsByKey = /* @__PURE__ */ new Map();
|
|
8415
8546
|
const obligationIdKeysById = /* @__PURE__ */ new Map();
|
|
8416
8547
|
for (const input of obligations$1) {
|
|
@@ -8420,32 +8551,49 @@ function create$23(db) {
|
|
|
8420
8551
|
if (!obligationIdKeysById.has(obligationId)) obligationIdKeysById.set(obligationId, input);
|
|
8421
8552
|
}
|
|
8422
8553
|
try {
|
|
8423
|
-
await db.transaction(async (dbTx) => {
|
|
8554
|
+
return await db.transaction(async (dbTx) => {
|
|
8424
8555
|
const obligationRows = Array.from(obligationsByKey.entries()).map(([obligationKey, item]) => ({
|
|
8425
8556
|
obligationKey,
|
|
8426
8557
|
loanToken: item.loanToken.toLowerCase(),
|
|
8427
8558
|
maturity: item.maturity,
|
|
8428
8559
|
rcfThreshold: item.rcfThreshold.toString()
|
|
8429
8560
|
}));
|
|
8430
|
-
|
|
8561
|
+
let obligationsInserted = 0;
|
|
8562
|
+
for (const batch of batch$1(obligationRows, DEFAULT_BATCH_SIZE)) {
|
|
8563
|
+
const inserted = await dbTx.insert(obligations).values(batch).onConflictDoNothing().returning();
|
|
8564
|
+
obligationsInserted += inserted.length;
|
|
8565
|
+
}
|
|
8431
8566
|
const obligationIdKeyRows = Array.from(obligationIdKeysById.entries()).map(([obligationId, input]) => ({
|
|
8432
8567
|
obligationId,
|
|
8433
8568
|
obligationKey: key(input.obligation).toLowerCase(),
|
|
8434
8569
|
chainId: input.chainId,
|
|
8435
8570
|
morphoV2: input.morphoV2.toLowerCase()
|
|
8436
8571
|
}));
|
|
8437
|
-
|
|
8572
|
+
let obligationIdKeysInserted = 0;
|
|
8573
|
+
for (const batch of batch$1(obligationIdKeyRows, DEFAULT_BATCH_SIZE)) {
|
|
8574
|
+
const inserted = await dbTx.insert(obligationIdKeys).values(batch).onConflictDoNothing().returning();
|
|
8575
|
+
obligationIdKeysInserted += inserted.length;
|
|
8576
|
+
}
|
|
8438
8577
|
const collateralRows = Array.from(obligationsByKey.entries()).flatMap(([obligationKey, item]) => {
|
|
8439
8578
|
return [...item.collaterals].sort((a, b) => a.asset.toLowerCase().localeCompare(b.asset.toLowerCase())).map((collateral, collateralIndex) => ({
|
|
8440
8579
|
obligationKey,
|
|
8441
8580
|
asset: collateral.asset.toLowerCase(),
|
|
8442
8581
|
oracleAddress: collateral.oracle.toLowerCase(),
|
|
8443
8582
|
lltv: collateral.lltv,
|
|
8444
|
-
maxLif: collateral.maxLif
|
|
8583
|
+
maxLif: collateral.maxLif,
|
|
8445
8584
|
collateralIndex
|
|
8446
8585
|
}));
|
|
8447
8586
|
});
|
|
8448
|
-
|
|
8587
|
+
let obligationCollateralsInserted = 0;
|
|
8588
|
+
for (const batch of batch$1(collateralRows, DEFAULT_BATCH_SIZE)) {
|
|
8589
|
+
const inserted = await dbTx.insert(obligationCollateralsV2).values(batch).onConflictDoNothing().returning();
|
|
8590
|
+
obligationCollateralsInserted += inserted.length;
|
|
8591
|
+
}
|
|
8592
|
+
return {
|
|
8593
|
+
obligationsInserted,
|
|
8594
|
+
obligationIdKeysInserted,
|
|
8595
|
+
obligationCollateralsInserted
|
|
8596
|
+
};
|
|
8449
8597
|
});
|
|
8450
8598
|
} catch (err) {
|
|
8451
8599
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -8529,8 +8677,8 @@ function create$22(config) {
|
|
|
8529
8677
|
jsonb_build_object(
|
|
8530
8678
|
'asset', ${obligationCollateralsV2.asset},
|
|
8531
8679
|
'oracle', ${obligationCollateralsV2.oracleAddress},
|
|
8532
|
-
'lltv', ${obligationCollateralsV2.lltv},
|
|
8533
|
-
'maxLif', ${obligationCollateralsV2.maxLif}
|
|
8680
|
+
'lltv', ${obligationCollateralsV2.lltv}::text,
|
|
8681
|
+
'maxLif', ${obligationCollateralsV2.maxLif}::text
|
|
8534
8682
|
)
|
|
8535
8683
|
),
|
|
8536
8684
|
'[]'::jsonb
|
|
@@ -8539,7 +8687,7 @@ function create$22(config) {
|
|
|
8539
8687
|
hash: offers.hash,
|
|
8540
8688
|
obligationId: offers.obligationId,
|
|
8541
8689
|
maker: offers.groupMaker,
|
|
8542
|
-
|
|
8690
|
+
maxUnits: offers.maxUnits,
|
|
8543
8691
|
tick: offers.tick,
|
|
8544
8692
|
maturity: offers.maturity,
|
|
8545
8693
|
rcfThreshold: obligations.rcfThreshold,
|
|
@@ -8562,7 +8710,7 @@ function create$22(config) {
|
|
|
8562
8710
|
hash: row.hash,
|
|
8563
8711
|
obligationId: row.obligationId,
|
|
8564
8712
|
maker: row.maker,
|
|
8565
|
-
|
|
8713
|
+
maxUnits: BigInt(row.maxUnits),
|
|
8566
8714
|
tick: row.tick,
|
|
8567
8715
|
maturity: from$15(row.maturity),
|
|
8568
8716
|
rcfThreshold: BigInt(row.rcfThreshold),
|
|
@@ -8577,7 +8725,7 @@ function create$22(config) {
|
|
|
8577
8725
|
asset: c.asset,
|
|
8578
8726
|
oracle: c.oracle,
|
|
8579
8727
|
lltv: BigInt(c.lltv),
|
|
8580
|
-
maxLif: BigInt(c.maxLif
|
|
8728
|
+
maxLif: BigInt(c.maxLif)
|
|
8581
8729
|
})).sort((a, b) => a.asset.toLowerCase().localeCompare(b.asset.toLowerCase())),
|
|
8582
8730
|
callback: {
|
|
8583
8731
|
address: row.callbackAddress,
|
|
@@ -8702,25 +8850,30 @@ function create$20(db) {
|
|
|
8702
8850
|
}));
|
|
8703
8851
|
},
|
|
8704
8852
|
upsert: async (oracles$2) => {
|
|
8705
|
-
if (oracles$2.length === 0) return;
|
|
8853
|
+
if (oracles$2.length === 0) return 0;
|
|
8706
8854
|
const rows = oracles$2.map((o) => ({
|
|
8707
8855
|
chainId: o.chainId,
|
|
8708
8856
|
address: o.address.toLowerCase(),
|
|
8709
8857
|
price: o.price !== null ? o.price.toString() : null,
|
|
8710
8858
|
blockNumber: o.blockNumber
|
|
8711
8859
|
}));
|
|
8712
|
-
await db.transaction(async (dbTx) => {
|
|
8713
|
-
|
|
8714
|
-
|
|
8715
|
-
|
|
8716
|
-
|
|
8717
|
-
|
|
8860
|
+
return await db.transaction(async (dbTx) => {
|
|
8861
|
+
let upsertedCount = 0;
|
|
8862
|
+
for (const batch of batch$1(rows, DEFAULT_BATCH_SIZE)) {
|
|
8863
|
+
const upserted = await dbTx.insert(oracles).values(batch).onConflictDoUpdate({
|
|
8864
|
+
target: [oracles.chainId, oracles.address],
|
|
8865
|
+
set: {
|
|
8866
|
+
price: sql`COALESCE(EXCLUDED.price, ${oracles.price})`,
|
|
8867
|
+
blockNumber: sql`CASE
|
|
8718
8868
|
WHEN EXCLUDED.price IS NULL THEN ${oracles.blockNumber}
|
|
8719
8869
|
ELSE EXCLUDED.block_number
|
|
8720
8870
|
END`,
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
|
|
8871
|
+
updatedAt: sql`NOW()`
|
|
8872
|
+
}
|
|
8873
|
+
}).returning();
|
|
8874
|
+
upsertedCount += upserted.length;
|
|
8875
|
+
}
|
|
8876
|
+
return upsertedCount;
|
|
8724
8877
|
});
|
|
8725
8878
|
}
|
|
8726
8879
|
};
|
|
@@ -8859,8 +9012,8 @@ const create$19 = (db) => {
|
|
|
8859
9012
|
l.obligation_id,
|
|
8860
9013
|
SUM(
|
|
8861
9014
|
CASE
|
|
8862
|
-
WHEN offer_agg.
|
|
8863
|
-
THEN COALESCE(g.consumed::numeric, 0) * (l.upper::numeric - l.lower::numeric) / offer_agg.
|
|
9015
|
+
WHEN offer_agg.max_units > 0
|
|
9016
|
+
THEN COALESCE(g.consumed::numeric, 0) * (l.upper::numeric - l.lower::numeric) / offer_agg.max_units
|
|
8864
9017
|
ELSE 0
|
|
8865
9018
|
END
|
|
8866
9019
|
) AS consumed
|
|
@@ -8875,7 +9028,7 @@ const create$19 = (db) => {
|
|
|
8875
9028
|
group_maker,
|
|
8876
9029
|
"group_group",
|
|
8877
9030
|
obligation_id,
|
|
8878
|
-
MAX(
|
|
9031
|
+
MAX(max_units::numeric) AS max_units
|
|
8879
9032
|
FROM ${offers}
|
|
8880
9033
|
GROUP BY group_chain_id, group_maker, "group_group", obligation_id
|
|
8881
9034
|
) offer_agg
|
|
@@ -9318,7 +9471,7 @@ function create$16(parameters) {
|
|
|
9318
9471
|
obligationId: obligationIdKeys.obligationId,
|
|
9319
9472
|
chainId: obligationIdKeys.chainId,
|
|
9320
9473
|
loanToken: obligations.loanToken,
|
|
9321
|
-
collaterals: sql`ARRAY_AGG(jsonb_build_object('asset', ${obligationCollateralsV2.asset}, 'oracle', ${obligationCollateralsV2.oracleAddress}, 'lltv', ${obligationCollateralsV2.lltv}))`.as("collaterals"),
|
|
9474
|
+
collaterals: sql`ARRAY_AGG(jsonb_build_object('asset', ${obligationCollateralsV2.asset}, 'oracle', ${obligationCollateralsV2.oracleAddress}, 'lltv', ${obligationCollateralsV2.lltv}::text, 'maxLif', ${obligationCollateralsV2.maxLif}::text))`.as("collaterals"),
|
|
9322
9475
|
maturity: obligations.maturity,
|
|
9323
9476
|
rcfThreshold: obligations.rcfThreshold,
|
|
9324
9477
|
askTick: sql`MAX(${bestQuotes.askTick})`.as("ask_tick"),
|
|
@@ -9351,7 +9504,8 @@ function create$16(parameters) {
|
|
|
9351
9504
|
collaterals: row.collaterals.sort((left, right) => left.asset.localeCompare(right.asset)).map((collateral) => from$13({
|
|
9352
9505
|
asset: collateral.asset,
|
|
9353
9506
|
oracle: collateral.oracle,
|
|
9354
|
-
lltv: from$14(BigInt(collateral.lltv))
|
|
9507
|
+
lltv: from$14(BigInt(collateral.lltv)),
|
|
9508
|
+
maxLif: BigInt(collateral.maxLif)
|
|
9355
9509
|
})),
|
|
9356
9510
|
maturity: row.maturity,
|
|
9357
9511
|
rcfThreshold: BigInt(row.rcfThreshold)
|
|
@@ -9811,7 +9965,7 @@ async function postMigrate(driver) {
|
|
|
9811
9965
|
WHERE o.group_chain_id = t.chain_id
|
|
9812
9966
|
AND o.group_maker = t.maker
|
|
9813
9967
|
AND o.group_group = t."group"
|
|
9814
|
-
AND o.
|
|
9968
|
+
AND o.max_units <= t.consumed;
|
|
9815
9969
|
RETURN NULL;
|
|
9816
9970
|
END;
|
|
9817
9971
|
$$;
|
|
@@ -9840,7 +9994,7 @@ async function postMigrate(driver) {
|
|
|
9840
9994
|
AND g.chain_id = t.group_chain_id
|
|
9841
9995
|
AND g.maker = t.group_maker
|
|
9842
9996
|
AND g."group" = t."group"
|
|
9843
|
-
AND o.
|
|
9997
|
+
AND o.max_units <= g.consumed;
|
|
9844
9998
|
RETURN NULL;
|
|
9845
9999
|
END;
|
|
9846
10000
|
$$;`);
|
|
@@ -10452,6 +10606,7 @@ const INDEXED_EVENT_PREFIX = "indexer.collector.";
|
|
|
10452
10606
|
const INDEXED_EVENT_SUFFIX$1 = "_indexed";
|
|
10453
10607
|
const LOGS_INGESTED_TOTAL_METRIC = "router_indexer_logs_ingested_total";
|
|
10454
10608
|
const LOGS_INDEXED_TOTAL_METRIC = "router_indexer_logs_indexed_total";
|
|
10609
|
+
const LOGS_DROPPED_TOTAL_METRIC = "router_indexer_logs_dropped_total";
|
|
10455
10610
|
const LOG_ENTRIES_TOTAL_METRIC = "router_indexer_log_entries_total";
|
|
10456
10611
|
const TICK_DURATION_SECONDS_METRIC = "router_indexer_tick_duration_seconds";
|
|
10457
10612
|
const TICK_PHASE_DURATION_SECONDS_METRIC = "router_indexer_tick_phase_duration_seconds";
|
|
@@ -10460,6 +10615,7 @@ const CHAIN_RPC_HEAD_AGE_SECONDS_METRIC = "router_indexer_chain_rpc_head_age_sec
|
|
|
10460
10615
|
const CHAIN_RPC_HEAD_UNAVAILABLE_TOTAL_METRIC = "router_indexer_chain_rpc_head_unavailable_total";
|
|
10461
10616
|
const ENTITIES_COMMITTED_TOTAL_METRIC = "router_indexer_entities_committed_total";
|
|
10462
10617
|
const ENTITIES_ATTEMPTED_TOTAL_METRIC = "router_indexer_entities_attempted_total";
|
|
10618
|
+
const DB_ROWS_COMMITTED_TOTAL_METRIC = "router_indexer_db_rows_committed_total";
|
|
10463
10619
|
const ENTITY_COMMIT_LAST_UNIXTIME_METRIC = "router_indexer_entity_commit_last_unixtime";
|
|
10464
10620
|
const COLLECTOR_COMMIT_LAST_UNIXTIME_METRIC = "router_indexer_collector_commit_last_unixtime";
|
|
10465
10621
|
const tickDurationBucketsSeconds = [
|
|
@@ -10517,6 +10673,11 @@ const chainSyncModeLabels = [
|
|
|
10517
10673
|
"unknown"
|
|
10518
10674
|
];
|
|
10519
10675
|
const headToDbLatencyExcludedEvents = new Set([INDEXER_COLLECTOR_TRANSFERS_INDEXED]);
|
|
10676
|
+
const droppedLogEvents = new Set([
|
|
10677
|
+
INDEXER_COLLECTOR_OFFER_TREE_DECODE_FAILED,
|
|
10678
|
+
INDEXER_COLLECTOR_OFFER_TREE_REJECTED,
|
|
10679
|
+
INDEXER_COLLECTOR_LOG_SKIPPED
|
|
10680
|
+
]);
|
|
10520
10681
|
const collectorNameByIndexedEvent$1 = new Map([
|
|
10521
10682
|
[INDEXER_COLLECTOR_OFFERS_INDEXED, "offers"],
|
|
10522
10683
|
[INDEXER_COLLECTOR_EVENTS_INDEXED, "morpho_v2"],
|
|
@@ -10541,6 +10702,16 @@ function create$15() {
|
|
|
10541
10702
|
labelNames: ["chain_id", "collector"],
|
|
10542
10703
|
registers: [registry]
|
|
10543
10704
|
});
|
|
10705
|
+
const logsDroppedTotal = new Counter({
|
|
10706
|
+
name: LOGS_DROPPED_TOTAL_METRIC,
|
|
10707
|
+
help: "Total collector inputs dropped for stable reasons.",
|
|
10708
|
+
labelNames: [
|
|
10709
|
+
"chain_id",
|
|
10710
|
+
"collector",
|
|
10711
|
+
"reason"
|
|
10712
|
+
],
|
|
10713
|
+
registers: [registry]
|
|
10714
|
+
});
|
|
10544
10715
|
const logEntriesTotal = new Counter({
|
|
10545
10716
|
name: LOG_ENTRIES_TOTAL_METRIC,
|
|
10546
10717
|
help: "Total indexer log entries by level.",
|
|
@@ -10603,6 +10774,17 @@ function create$15() {
|
|
|
10603
10774
|
],
|
|
10604
10775
|
registers: [registry]
|
|
10605
10776
|
});
|
|
10777
|
+
const dbRowsCommittedTotal = new Counter({
|
|
10778
|
+
name: DB_ROWS_COMMITTED_TOTAL_METRIC,
|
|
10779
|
+
help: "Total database rows inserted, upserted, or deleted by collector commits.",
|
|
10780
|
+
labelNames: [
|
|
10781
|
+
"chain_id",
|
|
10782
|
+
"collector",
|
|
10783
|
+
"table",
|
|
10784
|
+
"operation"
|
|
10785
|
+
],
|
|
10786
|
+
registers: [registry]
|
|
10787
|
+
});
|
|
10606
10788
|
const entityCommitLastUnixtime = new Gauge({
|
|
10607
10789
|
name: ENTITY_COMMIT_LAST_UNIXTIME_METRIC,
|
|
10608
10790
|
help: "Unix timestamp in seconds for the last successful entity commit.",
|
|
@@ -10638,8 +10820,11 @@ function create$15() {
|
|
|
10638
10820
|
return;
|
|
10639
10821
|
case "runtime.log": {
|
|
10640
10822
|
const level = normalizeLogLevel(observation.level);
|
|
10641
|
-
if (level
|
|
10642
|
-
|
|
10823
|
+
if (level !== null && observation.emitted !== false) logEntriesTotal.inc({ level }, 1);
|
|
10824
|
+
observeRuntimeLog({
|
|
10825
|
+
observation,
|
|
10826
|
+
logsDroppedTotal
|
|
10827
|
+
});
|
|
10643
10828
|
return;
|
|
10644
10829
|
}
|
|
10645
10830
|
case "commit.applied":
|
|
@@ -10647,6 +10832,7 @@ function create$15() {
|
|
|
10647
10832
|
observation,
|
|
10648
10833
|
entitiesCommittedTotal,
|
|
10649
10834
|
entitiesAttemptedTotal,
|
|
10835
|
+
dbRowsCommittedTotal,
|
|
10650
10836
|
entityCommitLastUnixtime,
|
|
10651
10837
|
collectorCommitLastUnixtime
|
|
10652
10838
|
});
|
|
@@ -10693,6 +10879,20 @@ function observeRuntimeEvent(parameters) {
|
|
|
10693
10879
|
if (headToDbInsertLatencyMs === null) return;
|
|
10694
10880
|
parameters.headToDbInsertLatencySeconds.observe(labels, sanitizeDurationSeconds(headToDbInsertLatencyMs / 1e3));
|
|
10695
10881
|
}
|
|
10882
|
+
function observeRuntimeLog(parameters) {
|
|
10883
|
+
const { observation } = parameters;
|
|
10884
|
+
if (observation.event === void 0 || !droppedLogEvents.has(observation.event)) return;
|
|
10885
|
+
const collector = normalizeLabelValue(observation.fields?.collector);
|
|
10886
|
+
const reason = normalizeLabelValue(observation.fields?.reason);
|
|
10887
|
+
if (collector === null || reason === null) return;
|
|
10888
|
+
const count = parseNonNegativeInt(observation.fields?.count) ?? 1;
|
|
10889
|
+
if (count <= 0) return;
|
|
10890
|
+
parameters.logsDroppedTotal.inc({
|
|
10891
|
+
chain_id: renderChainIdLabel(observation.chainId),
|
|
10892
|
+
collector,
|
|
10893
|
+
reason
|
|
10894
|
+
}, count);
|
|
10895
|
+
}
|
|
10696
10896
|
function observeCommitApplied(parameters) {
|
|
10697
10897
|
const { observation } = parameters;
|
|
10698
10898
|
const chainId = renderChainIdLabel(observation.chainId);
|
|
@@ -10726,6 +10926,19 @@ function observeCommitApplied(parameters) {
|
|
|
10726
10926
|
entity
|
|
10727
10927
|
}, committedAtUnixSeconds);
|
|
10728
10928
|
}
|
|
10929
|
+
for (const dbRow of observation.dbRows) {
|
|
10930
|
+
const collector = normalizeLabelValue(dbRow.collector);
|
|
10931
|
+
const table = normalizeLabelValue(dbRow.table);
|
|
10932
|
+
const operation = normalizeDbRowCommitOperation(dbRow.operation);
|
|
10933
|
+
const count = parseNonNegativeInt(dbRow.count);
|
|
10934
|
+
if (collector === null || table === null || operation === null || count === null || count <= 0) continue;
|
|
10935
|
+
parameters.dbRowsCommittedTotal.inc({
|
|
10936
|
+
chain_id: chainId,
|
|
10937
|
+
collector,
|
|
10938
|
+
table,
|
|
10939
|
+
operation
|
|
10940
|
+
}, count);
|
|
10941
|
+
}
|
|
10729
10942
|
}
|
|
10730
10943
|
function shouldObserveHeadToDbInsertLatency(event) {
|
|
10731
10944
|
return !headToDbLatencyExcludedEvents.has(event);
|
|
@@ -10751,6 +10964,10 @@ function normalizeCommitOperation(operation) {
|
|
|
10751
10964
|
if (operation === "inserted" || operation === "upserted" || operation === "deleted" || operation === "ignored") return operation;
|
|
10752
10965
|
return null;
|
|
10753
10966
|
}
|
|
10967
|
+
function normalizeDbRowCommitOperation(operation) {
|
|
10968
|
+
if (operation === "inserted" || operation === "upserted" || operation === "deleted") return operation;
|
|
10969
|
+
return null;
|
|
10970
|
+
}
|
|
10754
10971
|
function normalizeLabelValue(value) {
|
|
10755
10972
|
if (typeof value !== "string") return null;
|
|
10756
10973
|
const candidate = value.trim();
|
|
@@ -10843,7 +11060,7 @@ function create$14(parameters) {
|
|
|
10843
11060
|
});
|
|
10844
11061
|
}
|
|
10845
11062
|
},
|
|
10846
|
-
onCommitApplied: ({ collectors, stats, committedAtUnixMs }) => {
|
|
11063
|
+
onCommitApplied: ({ collectors, stats, dbRows, committedAtUnixMs }) => {
|
|
10847
11064
|
if (sinks.length === 0) return;
|
|
10848
11065
|
try {
|
|
10849
11066
|
emitObservation(sinks, {
|
|
@@ -10851,6 +11068,7 @@ function create$14(parameters) {
|
|
|
10851
11068
|
chainId,
|
|
10852
11069
|
collectors,
|
|
10853
11070
|
stats,
|
|
11071
|
+
dbRows,
|
|
10854
11072
|
committedAtUnixMs
|
|
10855
11073
|
});
|
|
10856
11074
|
} catch (error) {
|
|
@@ -10906,12 +11124,14 @@ function createObservedLogger(parameters) {
|
|
|
10906
11124
|
const wrap = (level, emit) => {
|
|
10907
11125
|
const enabled = isLogFnEnabled(emit);
|
|
10908
11126
|
return (entry) => {
|
|
10909
|
-
if (
|
|
11127
|
+
if (isIndexerComponent(entry.component) && (enabled || isStructuredCollectorDropLog(entry))) try {
|
|
10910
11128
|
const chainId = parseChainId(entry.chain_id);
|
|
10911
11129
|
if (chainId !== null) parameters.onLogEntry({
|
|
10912
11130
|
type: "runtime.log",
|
|
10913
11131
|
chainId,
|
|
10914
|
-
level
|
|
11132
|
+
level,
|
|
11133
|
+
...extractRuntimeLogMetadata(entry),
|
|
11134
|
+
...enabled ? {} : { emitted: false }
|
|
10915
11135
|
});
|
|
10916
11136
|
} catch {}
|
|
10917
11137
|
emit(entry);
|
|
@@ -10926,6 +11146,18 @@ function createObservedLogger(parameters) {
|
|
|
10926
11146
|
fatal: wrap("fatal", parameters.logger.fatal)
|
|
10927
11147
|
};
|
|
10928
11148
|
}
|
|
11149
|
+
function extractRuntimeLogMetadata(entry) {
|
|
11150
|
+
const event = typeof entry.event === "string" ? entry.event : void 0;
|
|
11151
|
+
const fields = Object.fromEntries(Object.entries(entry).filter(([key]) => key !== "msg" && key !== "component" && key !== "chain_id" && key !== "event"));
|
|
11152
|
+
return {
|
|
11153
|
+
...event === void 0 ? {} : { event },
|
|
11154
|
+
...Object.keys(fields).length === 0 ? {} : { fields }
|
|
11155
|
+
};
|
|
11156
|
+
}
|
|
11157
|
+
function isStructuredCollectorDropLog(entry) {
|
|
11158
|
+
if (entry.event !== INDEXER_COLLECTOR_OFFER_TREE_DECODE_FAILED && entry.event !== INDEXER_COLLECTOR_OFFER_TREE_REJECTED && entry.event !== INDEXER_COLLECTOR_LOG_SKIPPED) return false;
|
|
11159
|
+
return typeof entry.collector === "string" && typeof entry.reason === "string";
|
|
11160
|
+
}
|
|
10929
11161
|
function emitObservation(sinks, observation) {
|
|
10930
11162
|
for (const sink of sinks) sink.observe(observation);
|
|
10931
11163
|
}
|
|
@@ -10999,7 +11231,7 @@ async function getBook(params, db) {
|
|
|
10999
11231
|
levels_count: levels.length,
|
|
11000
11232
|
has_next_cursor: nextCursor != null,
|
|
11001
11233
|
first_level_tick: firstLevel?.tick ?? null,
|
|
11002
|
-
|
|
11234
|
+
first_level_max_units: firstLevel?.maxUnits.toString() ?? null,
|
|
11003
11235
|
first_level_count: firstLevel?.count ?? null
|
|
11004
11236
|
});
|
|
11005
11237
|
return success({
|
|
@@ -11418,8 +11650,8 @@ async function getOffersQuery(db, parameters) {
|
|
|
11418
11650
|
COALESCE(jsonb_agg(jsonb_build_object(
|
|
11419
11651
|
'asset', oc.asset,
|
|
11420
11652
|
'oracle', oc.oracle_address,
|
|
11421
|
-
'lltv', oc.lltv,
|
|
11422
|
-
'maxLif', oc.max_lif
|
|
11653
|
+
'lltv', oc.lltv::text,
|
|
11654
|
+
'maxLif', oc.max_lif::text
|
|
11423
11655
|
) ORDER BY oc.asset), '[]'::jsonb) AS collaterals
|
|
11424
11656
|
FROM ${obligationIdKeys} oia
|
|
11425
11657
|
JOIN ${obligationCollateralsV2} oc
|
|
@@ -11436,7 +11668,7 @@ async function getOffersQuery(db, parameters) {
|
|
|
11436
11668
|
mo.hash,
|
|
11437
11669
|
mo.obligation_id,
|
|
11438
11670
|
mo.group_maker,
|
|
11439
|
-
mo.
|
|
11671
|
+
mo.max_units,
|
|
11440
11672
|
mo.consumed,
|
|
11441
11673
|
mo.tick,
|
|
11442
11674
|
mo.maturity,
|
|
@@ -11468,11 +11700,14 @@ async function getOffersQuery(db, parameters) {
|
|
|
11468
11700
|
ORDER BY mo.hash ASC, mo.obligation_id ASC;
|
|
11469
11701
|
`)).rows.map((row) => {
|
|
11470
11702
|
const receiverIfMakerIsSeller = (row.receiver_if_maker_is_seller ?? row.group_maker).toLowerCase();
|
|
11703
|
+
const maxUnits = BigInt(row.max_units ?? 0);
|
|
11704
|
+
const consumed = BigInt(row.consumed ?? 0);
|
|
11705
|
+
const remainingUnits = maxUnits > consumed ? maxUnits - consumed : 0n;
|
|
11471
11706
|
return {
|
|
11472
11707
|
hash: row.hash,
|
|
11473
11708
|
obligationId: row.obligation_id,
|
|
11474
11709
|
maker: row.group_maker,
|
|
11475
|
-
|
|
11710
|
+
maxUnits,
|
|
11476
11711
|
tick: row.tick,
|
|
11477
11712
|
maturity: row.maturity,
|
|
11478
11713
|
expiry: row.expiry,
|
|
@@ -11487,7 +11722,7 @@ async function getOffersQuery(db, parameters) {
|
|
|
11487
11722
|
asset: c.asset,
|
|
11488
11723
|
oracle: c.oracle,
|
|
11489
11724
|
lltv: BigInt(c.lltv),
|
|
11490
|
-
maxLif: BigInt(c.maxLif
|
|
11725
|
+
maxLif: BigInt(c.maxLif)
|
|
11491
11726
|
})).sort((a, b) => a.asset.toLowerCase().localeCompare(b.asset.toLowerCase())),
|
|
11492
11727
|
callback: {
|
|
11493
11728
|
address: row.callback_address,
|
|
@@ -11495,9 +11730,9 @@ async function getOffersQuery(db, parameters) {
|
|
|
11495
11730
|
},
|
|
11496
11731
|
receiverIfMakerIsSeller,
|
|
11497
11732
|
exitOnly: row.exit_only,
|
|
11498
|
-
consumed
|
|
11733
|
+
consumed,
|
|
11499
11734
|
available: BigInt(String(row.available ?? "0").split(".")[0] ?? "0"),
|
|
11500
|
-
takeable:
|
|
11735
|
+
takeable: assetsToUnits(BigInt(String(row.takeable ?? "0").split(".")[0] ?? "0"), row.tick, row.buy, remainingUnits),
|
|
11501
11736
|
blockNumber: row.block_number,
|
|
11502
11737
|
root: row.tree_root ? row.tree_root.toLowerCase() : void 0,
|
|
11503
11738
|
signature: row.root_signature ? row.root_signature.toLowerCase() : void 0,
|
|
@@ -11541,7 +11776,8 @@ async function getOffers(queryParameters, db) {
|
|
|
11541
11776
|
side: query.side,
|
|
11542
11777
|
obligationId: query.obligation_id,
|
|
11543
11778
|
cursor: query.cursor,
|
|
11544
|
-
limit: query.limit
|
|
11779
|
+
limit: query.limit,
|
|
11780
|
+
requirePositiveTakeableAssets: true
|
|
11545
11781
|
});
|
|
11546
11782
|
logger.debug({
|
|
11547
11783
|
service: "api_controller",
|
|
@@ -11693,6 +11929,7 @@ function createApp$1(parameters) {
|
|
|
11693
11929
|
origin: "*",
|
|
11694
11930
|
exposeHeaders: ["x-request-id"]
|
|
11695
11931
|
}));
|
|
11932
|
+
app.get("/", (c) => c.redirect("/docs"));
|
|
11696
11933
|
app.get("/v1/offers", async (c) => {
|
|
11697
11934
|
const { statusCode, body } = await services.getOffers(c.req.query());
|
|
11698
11935
|
return c.json(body, statusCode);
|
|
@@ -12117,6 +12354,10 @@ function* ask(operation) {
|
|
|
12117
12354
|
|
|
12118
12355
|
//#endregion
|
|
12119
12356
|
//#region src/indexer/engine/adapter/appliers/applyChainState.ts
|
|
12357
|
+
const emptyOutcome = () => ({
|
|
12358
|
+
stats: [],
|
|
12359
|
+
dbRows: []
|
|
12360
|
+
});
|
|
12120
12361
|
function isChainUninitializedError$1(error) {
|
|
12121
12362
|
return error instanceof Error && error.message.includes("Chain state not initialized");
|
|
12122
12363
|
}
|
|
@@ -12165,7 +12406,7 @@ const chainStateAppliers = {
|
|
|
12165
12406
|
context.chainMutationState.expectedTipHashForWrite = advanceParameters.tipHash;
|
|
12166
12407
|
}
|
|
12167
12408
|
context.chainMutationState.expectedChainState = nextChainState;
|
|
12168
|
-
return
|
|
12409
|
+
return emptyOutcome();
|
|
12169
12410
|
},
|
|
12170
12411
|
collector: async ({ mutation, dbTx, context }) => {
|
|
12171
12412
|
const collectorName = context.toCollectorName(mutation.name);
|
|
@@ -12179,7 +12420,7 @@ const chainStateAppliers = {
|
|
|
12179
12420
|
blockNumber: mutation.cursor,
|
|
12180
12421
|
epoch: BigInt(mutation.epoch)
|
|
12181
12422
|
});
|
|
12182
|
-
return
|
|
12423
|
+
return emptyOutcome();
|
|
12183
12424
|
}
|
|
12184
12425
|
};
|
|
12185
12426
|
|
|
@@ -12192,33 +12433,66 @@ const LOTS_PENDING_LINK_TYPE = "offers_lots_missing_group";
|
|
|
12192
12433
|
|
|
12193
12434
|
//#endregion
|
|
12194
12435
|
//#region src/indexer/engine/adapter/appliers/applyMorphoV2.ts
|
|
12436
|
+
const outcome$3 = (parameters) => ({
|
|
12437
|
+
stats: parameters.stats ?? [],
|
|
12438
|
+
dbRows: parameters.dbRows ?? []
|
|
12439
|
+
});
|
|
12195
12440
|
const morphoV2Appliers = {
|
|
12196
12441
|
transfers_create: async ({ mutation, dbTx }) => {
|
|
12197
|
-
await dbTx.transfers.create(mutation.rows);
|
|
12198
|
-
return
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
|
|
12442
|
+
const insertedTransfers = await dbTx.transfers.create(mutation.rows);
|
|
12443
|
+
return outcome$3({
|
|
12444
|
+
stats: mutation.rows.length > 0 ? [{
|
|
12445
|
+
entity: "transfer",
|
|
12446
|
+
operation: "inserted",
|
|
12447
|
+
count: mutation.rows.length
|
|
12448
|
+
}] : [],
|
|
12449
|
+
dbRows: insertedTransfers > 0 ? [{
|
|
12450
|
+
table: "transfers",
|
|
12451
|
+
operation: "inserted",
|
|
12452
|
+
count: insertedTransfers
|
|
12453
|
+
}] : []
|
|
12454
|
+
});
|
|
12203
12455
|
},
|
|
12204
12456
|
consumed_create: async ({ mutation, dbTx }) => {
|
|
12205
|
-
await dbTx.consumed.create(mutation.rows);
|
|
12206
|
-
return
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12457
|
+
const inserted = await dbTx.consumed.create(mutation.rows);
|
|
12458
|
+
return outcome$3({
|
|
12459
|
+
stats: mutation.rows.length > 0 ? [{
|
|
12460
|
+
entity: "consumed_event",
|
|
12461
|
+
operation: "inserted",
|
|
12462
|
+
count: mutation.rows.length
|
|
12463
|
+
}] : [],
|
|
12464
|
+
dbRows: [...inserted.groupsInserted > 0 ? [{
|
|
12465
|
+
table: "groups",
|
|
12466
|
+
operation: "inserted",
|
|
12467
|
+
count: inserted.groupsInserted
|
|
12468
|
+
}] : [], ...inserted.consumedEventsInserted > 0 ? [{
|
|
12469
|
+
table: "consumed_events",
|
|
12470
|
+
operation: "inserted",
|
|
12471
|
+
count: inserted.consumedEventsInserted
|
|
12472
|
+
}] : []]
|
|
12473
|
+
});
|
|
12211
12474
|
},
|
|
12212
12475
|
seizures_record: async ({ mutation, dbTx, context }) => {
|
|
12213
|
-
await context.pendingStore.applySeizureFacts({
|
|
12476
|
+
const materialized = await context.pendingStore.applySeizureFacts({
|
|
12214
12477
|
dbTx,
|
|
12215
12478
|
seizureFacts: mutation.rows
|
|
12216
12479
|
});
|
|
12217
|
-
return
|
|
12218
|
-
|
|
12219
|
-
|
|
12220
|
-
|
|
12221
|
-
|
|
12480
|
+
return outcome$3({
|
|
12481
|
+
stats: mutation.rows.length > 0 ? [{
|
|
12482
|
+
entity: "seizure_fact",
|
|
12483
|
+
operation: "inserted",
|
|
12484
|
+
count: mutation.rows.length
|
|
12485
|
+
}] : [],
|
|
12486
|
+
dbRows: [...materialized.positionsUpserted > 0 ? [{
|
|
12487
|
+
table: "positions",
|
|
12488
|
+
operation: "upserted",
|
|
12489
|
+
count: materialized.positionsUpserted
|
|
12490
|
+
}] : [], ...materialized.transfersInserted > 0 ? [{
|
|
12491
|
+
table: "transfers",
|
|
12492
|
+
operation: "inserted",
|
|
12493
|
+
count: materialized.transfersInserted
|
|
12494
|
+
}] : []]
|
|
12495
|
+
});
|
|
12222
12496
|
},
|
|
12223
12497
|
morpho_v2_rewind: async ({ mutation, dbTx, context }) => {
|
|
12224
12498
|
const deletedConsumedEvents = await dbTx.consumed.delete({
|
|
@@ -12242,17 +12516,35 @@ const morphoV2Appliers = {
|
|
|
12242
12516
|
});
|
|
12243
12517
|
const deletedTransfers = deletedDebtTransfers + deletedCollateralTransfers;
|
|
12244
12518
|
const stats = [];
|
|
12245
|
-
|
|
12246
|
-
|
|
12247
|
-
|
|
12248
|
-
|
|
12249
|
-
|
|
12250
|
-
|
|
12251
|
-
|
|
12252
|
-
|
|
12253
|
-
|
|
12519
|
+
const dbRows = [];
|
|
12520
|
+
if (deletedConsumedEvents > 0) {
|
|
12521
|
+
stats.push({
|
|
12522
|
+
entity: "consumed_event",
|
|
12523
|
+
operation: "deleted",
|
|
12524
|
+
count: deletedConsumedEvents
|
|
12525
|
+
});
|
|
12526
|
+
dbRows.push({
|
|
12527
|
+
table: "consumed_events",
|
|
12528
|
+
operation: "deleted",
|
|
12529
|
+
count: deletedConsumedEvents
|
|
12530
|
+
});
|
|
12531
|
+
}
|
|
12532
|
+
if (deletedTransfers > 0) {
|
|
12533
|
+
stats.push({
|
|
12534
|
+
entity: "transfer",
|
|
12535
|
+
operation: "deleted",
|
|
12536
|
+
count: deletedTransfers
|
|
12537
|
+
});
|
|
12538
|
+
dbRows.push({
|
|
12539
|
+
table: "transfers",
|
|
12540
|
+
operation: "deleted",
|
|
12541
|
+
count: deletedTransfers
|
|
12542
|
+
});
|
|
12543
|
+
}
|
|
12544
|
+
return outcome$3({
|
|
12545
|
+
stats,
|
|
12546
|
+
dbRows
|
|
12254
12547
|
});
|
|
12255
|
-
return stats;
|
|
12256
12548
|
}
|
|
12257
12549
|
};
|
|
12258
12550
|
|
|
@@ -12263,7 +12555,12 @@ const buildGroupReferenceKey = (chainId, maker, group) => `${chainId}:${maker.to
|
|
|
12263
12555
|
const buildCallbacksMissingOfferReference = (row) => `${row.offerHash.toLowerCase()}:${row.obligationId.toLowerCase()}`;
|
|
12264
12556
|
const buildMerklePathMissingOfferReference = (row) => `${row.offerHash.toLowerCase()}:${row.obligationId.toLowerCase()}:${row.treeRoot.toLowerCase()}`;
|
|
12265
12557
|
const buildLotMissingGroupReference = (row) => `${row.positionChainId}:${row.positionUser.toLowerCase()}:${row.group.toLowerCase()}:${row.obligationId.toLowerCase()}`;
|
|
12266
|
-
const
|
|
12558
|
+
const entityStat = (parameters) => parameters.count > 0 ? [parameters] : [];
|
|
12559
|
+
const dbRowStat = (parameters) => parameters.count > 0 ? [parameters] : [];
|
|
12560
|
+
const outcome$2 = (parameters) => ({
|
|
12561
|
+
stats: parameters.stats ?? [],
|
|
12562
|
+
dbRows: parameters.dbRows ?? []
|
|
12563
|
+
});
|
|
12267
12564
|
async function selectExistingOfferKeys(parameters) {
|
|
12268
12565
|
const { context, dbTx, references } = parameters;
|
|
12269
12566
|
if (references.length === 0) return /* @__PURE__ */ new Set();
|
|
@@ -12344,45 +12641,93 @@ async function partitionLotsByGroupExistence(parameters) {
|
|
|
12344
12641
|
}
|
|
12345
12642
|
const offersAppliers = {
|
|
12346
12643
|
obligations_create: async ({ mutation, dbTx }) => {
|
|
12347
|
-
await dbTx.obligations.create(mutation.rows);
|
|
12348
|
-
return
|
|
12349
|
-
|
|
12350
|
-
|
|
12351
|
-
|
|
12644
|
+
const inserted = await dbTx.obligations.create(mutation.rows);
|
|
12645
|
+
return outcome$2({
|
|
12646
|
+
stats: entityStat({
|
|
12647
|
+
entity: "obligation",
|
|
12648
|
+
operation: "inserted",
|
|
12649
|
+
count: mutation.rows.length
|
|
12650
|
+
}),
|
|
12651
|
+
dbRows: [
|
|
12652
|
+
...dbRowStat({
|
|
12653
|
+
table: "obligations",
|
|
12654
|
+
operation: "inserted",
|
|
12655
|
+
count: inserted.obligationsInserted
|
|
12656
|
+
}),
|
|
12657
|
+
...dbRowStat({
|
|
12658
|
+
table: "obligation_id_keys",
|
|
12659
|
+
operation: "inserted",
|
|
12660
|
+
count: inserted.obligationIdKeysInserted
|
|
12661
|
+
}),
|
|
12662
|
+
...dbRowStat({
|
|
12663
|
+
table: "obligation_collaterals_v2",
|
|
12664
|
+
operation: "inserted",
|
|
12665
|
+
count: inserted.obligationCollateralsInserted
|
|
12666
|
+
})
|
|
12667
|
+
]
|
|
12352
12668
|
});
|
|
12353
12669
|
},
|
|
12354
12670
|
groups_create: async ({ mutation, dbTx }) => {
|
|
12355
|
-
await dbTx.groups.create(mutation.rows);
|
|
12356
|
-
return
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12671
|
+
const insertedGroups = await dbTx.groups.create(mutation.rows);
|
|
12672
|
+
return outcome$2({
|
|
12673
|
+
stats: entityStat({
|
|
12674
|
+
entity: "group",
|
|
12675
|
+
operation: "inserted",
|
|
12676
|
+
count: mutation.rows.length
|
|
12677
|
+
}),
|
|
12678
|
+
dbRows: dbRowStat({
|
|
12679
|
+
table: "groups",
|
|
12680
|
+
operation: "inserted",
|
|
12681
|
+
count: insertedGroups
|
|
12682
|
+
})
|
|
12360
12683
|
});
|
|
12361
12684
|
},
|
|
12362
12685
|
offers_create: async ({ mutation, dbTx }) => {
|
|
12363
|
-
await dbTx.offers.create(mutation.batches);
|
|
12364
|
-
return
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
|
|
12686
|
+
const insertedOffers = await dbTx.offers.create(mutation.batches);
|
|
12687
|
+
return outcome$2({
|
|
12688
|
+
stats: entityStat({
|
|
12689
|
+
entity: "offer",
|
|
12690
|
+
operation: "inserted",
|
|
12691
|
+
count: insertedOffers.length
|
|
12692
|
+
}),
|
|
12693
|
+
dbRows: dbRowStat({
|
|
12694
|
+
table: "offers",
|
|
12695
|
+
operation: "inserted",
|
|
12696
|
+
count: insertedOffers.length
|
|
12697
|
+
})
|
|
12368
12698
|
});
|
|
12369
12699
|
},
|
|
12370
12700
|
offers_rewind: async ({ mutation, dbTx, context }) => {
|
|
12371
|
-
|
|
12372
|
-
|
|
12373
|
-
|
|
12374
|
-
|
|
12375
|
-
|
|
12376
|
-
|
|
12701
|
+
const deletedOffers = await dbTx.offers.delete({
|
|
12702
|
+
chainId: context.chainId,
|
|
12703
|
+
blockNumberGte: mutation.blockNumberGte
|
|
12704
|
+
});
|
|
12705
|
+
return outcome$2({
|
|
12706
|
+
stats: entityStat({
|
|
12707
|
+
entity: "offer",
|
|
12708
|
+
operation: "deleted",
|
|
12709
|
+
count: deletedOffers
|
|
12710
|
+
}),
|
|
12711
|
+
dbRows: dbRowStat({
|
|
12712
|
+
table: "offers",
|
|
12713
|
+
operation: "deleted",
|
|
12714
|
+
count: deletedOffers
|
|
12377
12715
|
})
|
|
12378
12716
|
});
|
|
12379
12717
|
},
|
|
12380
12718
|
trees_upsert: async ({ mutation, dbTx }) => {
|
|
12381
|
-
await dbTx.trees.upsert(mutation.rows);
|
|
12382
|
-
return
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12719
|
+
const upsertedRoots = await dbTx.trees.upsert(mutation.rows);
|
|
12720
|
+
return outcome$2({
|
|
12721
|
+
stats: entityStat({
|
|
12722
|
+
entity: "tree",
|
|
12723
|
+
operation: "upserted",
|
|
12724
|
+
count: mutation.rows.length
|
|
12725
|
+
}),
|
|
12726
|
+
dbRows: dbRowStat({
|
|
12727
|
+
table: "trees",
|
|
12728
|
+
operation: "upserted",
|
|
12729
|
+
count: upsertedRoots.length
|
|
12730
|
+
})
|
|
12386
12731
|
});
|
|
12387
12732
|
},
|
|
12388
12733
|
trees_upsert_paths: async ({ mutation, dbTx, context }) => {
|
|
@@ -12403,15 +12748,22 @@ const offersAppliers = {
|
|
|
12403
12748
|
blockNumber: context.pendingLinkReferenceBlockNumber()
|
|
12404
12749
|
}))
|
|
12405
12750
|
});
|
|
12406
|
-
return
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
|
|
12411
|
-
|
|
12412
|
-
|
|
12413
|
-
|
|
12414
|
-
|
|
12751
|
+
return outcome$2({
|
|
12752
|
+
stats: [...entityStat({
|
|
12753
|
+
entity: "tree_path",
|
|
12754
|
+
operation: "upserted",
|
|
12755
|
+
count: resolvableRows.length
|
|
12756
|
+
}), ...entityStat({
|
|
12757
|
+
entity: "tree_path",
|
|
12758
|
+
operation: "ignored",
|
|
12759
|
+
count: missingRows.length
|
|
12760
|
+
})],
|
|
12761
|
+
dbRows: dbRowStat({
|
|
12762
|
+
table: "merkle_paths",
|
|
12763
|
+
operation: "upserted",
|
|
12764
|
+
count: resolvableRows.length
|
|
12765
|
+
})
|
|
12766
|
+
});
|
|
12415
12767
|
},
|
|
12416
12768
|
callbacks_upsert: async ({ mutation, dbTx, context }) => {
|
|
12417
12769
|
const { resolvableRows, missingRows } = await partitionCallbacksByOfferExistence({
|
|
@@ -12419,7 +12771,10 @@ const offersAppliers = {
|
|
|
12419
12771
|
dbTx,
|
|
12420
12772
|
rows: mutation.rows
|
|
12421
12773
|
});
|
|
12422
|
-
|
|
12774
|
+
const inserted = resolvableRows.length > 0 ? await dbTx.callbacks.upsert(resolvableRows) : {
|
|
12775
|
+
callbacksInserted: 0,
|
|
12776
|
+
offersCallbacksInserted: 0
|
|
12777
|
+
};
|
|
12423
12778
|
await context.pendingStore.recordIgnoredLinks({
|
|
12424
12779
|
dbTx,
|
|
12425
12780
|
records: missingRows.map((row) => ({
|
|
@@ -12431,22 +12786,36 @@ const offersAppliers = {
|
|
|
12431
12786
|
blockNumber: context.pendingLinkReferenceBlockNumber()
|
|
12432
12787
|
}))
|
|
12433
12788
|
});
|
|
12434
|
-
return
|
|
12435
|
-
|
|
12436
|
-
|
|
12437
|
-
|
|
12438
|
-
|
|
12439
|
-
|
|
12440
|
-
|
|
12441
|
-
|
|
12442
|
-
|
|
12789
|
+
return outcome$2({
|
|
12790
|
+
stats: [...entityStat({
|
|
12791
|
+
entity: "callback",
|
|
12792
|
+
operation: "upserted",
|
|
12793
|
+
count: resolvableRows.length
|
|
12794
|
+
}), ...entityStat({
|
|
12795
|
+
entity: "callback",
|
|
12796
|
+
operation: "ignored",
|
|
12797
|
+
count: missingRows.length
|
|
12798
|
+
})],
|
|
12799
|
+
dbRows: [...dbRowStat({
|
|
12800
|
+
table: "callbacks",
|
|
12801
|
+
operation: "inserted",
|
|
12802
|
+
count: inserted.callbacksInserted
|
|
12803
|
+
}), ...dbRowStat({
|
|
12804
|
+
table: "offers_callbacks",
|
|
12805
|
+
operation: "inserted",
|
|
12806
|
+
count: inserted.offersCallbacksInserted
|
|
12807
|
+
})]
|
|
12808
|
+
});
|
|
12443
12809
|
},
|
|
12444
12810
|
lots_create: async ({ mutation, dbTx, context }) => {
|
|
12445
12811
|
const { resolvableRows, missingRows } = await partitionLotsByGroupExistence({
|
|
12446
12812
|
dbTx,
|
|
12447
12813
|
rows: mutation.rows
|
|
12448
12814
|
});
|
|
12449
|
-
|
|
12815
|
+
const inserted = resolvableRows.length > 0 ? await dbTx.lots.create(resolvableRows) : {
|
|
12816
|
+
lotsPositionsInserted: 0,
|
|
12817
|
+
lotsInserted: 0
|
|
12818
|
+
};
|
|
12450
12819
|
await context.pendingStore.recordIgnoredLinks({
|
|
12451
12820
|
dbTx,
|
|
12452
12821
|
records: missingRows.map((row) => ({
|
|
@@ -12458,43 +12827,76 @@ const offersAppliers = {
|
|
|
12458
12827
|
blockNumber: context.pendingLinkReferenceBlockNumber()
|
|
12459
12828
|
}))
|
|
12460
12829
|
});
|
|
12461
|
-
return
|
|
12462
|
-
|
|
12463
|
-
|
|
12464
|
-
|
|
12465
|
-
|
|
12466
|
-
|
|
12467
|
-
|
|
12468
|
-
|
|
12469
|
-
|
|
12830
|
+
return outcome$2({
|
|
12831
|
+
stats: [...entityStat({
|
|
12832
|
+
entity: "lot",
|
|
12833
|
+
operation: "inserted",
|
|
12834
|
+
count: resolvableRows.length
|
|
12835
|
+
}), ...entityStat({
|
|
12836
|
+
entity: "lot",
|
|
12837
|
+
operation: "ignored",
|
|
12838
|
+
count: missingRows.length
|
|
12839
|
+
})],
|
|
12840
|
+
dbRows: [...dbRowStat({
|
|
12841
|
+
table: "lots_positions",
|
|
12842
|
+
operation: "inserted",
|
|
12843
|
+
count: inserted.lotsPositionsInserted
|
|
12844
|
+
}), ...dbRowStat({
|
|
12845
|
+
table: "lots",
|
|
12846
|
+
operation: "inserted",
|
|
12847
|
+
count: inserted.lotsInserted
|
|
12848
|
+
})]
|
|
12849
|
+
});
|
|
12470
12850
|
}
|
|
12471
12851
|
};
|
|
12472
12852
|
|
|
12473
12853
|
//#endregion
|
|
12474
12854
|
//#region src/indexer/engine/adapter/appliers/applyOracle.ts
|
|
12855
|
+
const outcome$1 = (parameters) => ({
|
|
12856
|
+
stats: parameters.stats ?? [],
|
|
12857
|
+
dbRows: parameters.dbRows ?? []
|
|
12858
|
+
});
|
|
12475
12859
|
const oracleApplier = { oracle: async ({ mutation, dbTx, context }) => {
|
|
12476
|
-
await dbTx.oracles.upsert(mutation.rows.map((row) => ({
|
|
12860
|
+
const upsertedOracles = await dbTx.oracles.upsert(mutation.rows.map((row) => ({
|
|
12477
12861
|
chainId: context.chainId,
|
|
12478
12862
|
...row,
|
|
12479
12863
|
address: row.address
|
|
12480
12864
|
})));
|
|
12481
|
-
return
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
|
|
12485
|
-
|
|
12865
|
+
return outcome$1({
|
|
12866
|
+
stats: mutation.rows.length > 0 ? [{
|
|
12867
|
+
entity: "oracle",
|
|
12868
|
+
operation: "upserted",
|
|
12869
|
+
count: mutation.rows.length
|
|
12870
|
+
}] : [],
|
|
12871
|
+
dbRows: upsertedOracles > 0 ? [{
|
|
12872
|
+
table: "oracles",
|
|
12873
|
+
operation: "upserted",
|
|
12874
|
+
count: upsertedOracles
|
|
12875
|
+
}] : []
|
|
12876
|
+
});
|
|
12486
12877
|
} };
|
|
12487
12878
|
|
|
12488
12879
|
//#endregion
|
|
12489
12880
|
//#region src/indexer/engine/adapter/appliers/applyPositions.ts
|
|
12881
|
+
const outcome = (parameters) => ({
|
|
12882
|
+
stats: parameters.stats ?? [],
|
|
12883
|
+
dbRows: parameters.dbRows ?? []
|
|
12884
|
+
});
|
|
12490
12885
|
const positionsAppliers = {
|
|
12491
12886
|
positions_upsert: async ({ mutation, dbTx }) => {
|
|
12492
|
-
await dbTx.positions.upsert(mutation.rows);
|
|
12493
|
-
return
|
|
12494
|
-
|
|
12495
|
-
|
|
12496
|
-
|
|
12497
|
-
|
|
12887
|
+
const upsertedPositions = await dbTx.positions.upsert(mutation.rows);
|
|
12888
|
+
return outcome({
|
|
12889
|
+
stats: mutation.rows.length > 0 ? [{
|
|
12890
|
+
entity: "position",
|
|
12891
|
+
operation: "upserted",
|
|
12892
|
+
count: mutation.rows.length
|
|
12893
|
+
}] : [],
|
|
12894
|
+
dbRows: upsertedPositions > 0 ? [{
|
|
12895
|
+
table: "positions",
|
|
12896
|
+
operation: "upserted",
|
|
12897
|
+
count: upsertedPositions
|
|
12898
|
+
}] : []
|
|
12899
|
+
});
|
|
12498
12900
|
},
|
|
12499
12901
|
positions_rewind: async ({ mutation, dbTx, context }) => {
|
|
12500
12902
|
const deletedPositions = await dbTx.positions.setEmptyAfter({
|
|
@@ -12502,11 +12904,11 @@ const positionsAppliers = {
|
|
|
12502
12904
|
blockNumber: mutation.blockNumberGte,
|
|
12503
12905
|
type: Type.ERC20
|
|
12504
12906
|
});
|
|
12505
|
-
return deletedPositions > 0 ? [{
|
|
12907
|
+
return outcome({ stats: deletedPositions > 0 ? [{
|
|
12506
12908
|
entity: "position",
|
|
12507
12909
|
operation: "deleted",
|
|
12508
12910
|
count: deletedPositions
|
|
12509
|
-
}] : [];
|
|
12911
|
+
}] : [] });
|
|
12510
12912
|
}
|
|
12511
12913
|
};
|
|
12512
12914
|
|
|
@@ -12819,7 +13221,9 @@ async function materializeSeizureFacts(parameters) {
|
|
|
12819
13221
|
if (seizureFacts.length === 0) return {
|
|
12820
13222
|
unresolvedFacts: [],
|
|
12821
13223
|
transfersCreate: [],
|
|
12822
|
-
positionsUpsert: []
|
|
13224
|
+
positionsUpsert: [],
|
|
13225
|
+
transfersInserted: 0,
|
|
13226
|
+
positionsUpserted: 0
|
|
12823
13227
|
};
|
|
12824
13228
|
const resolutionMap = await resolveCollateralAssetRefs({
|
|
12825
13229
|
dbTx,
|
|
@@ -12847,9 +13251,11 @@ async function materializeSeizureFacts(parameters) {
|
|
|
12847
13251
|
}));
|
|
12848
13252
|
}
|
|
12849
13253
|
const positionsUpsert = toCollateralPositionRows(resolvedTransfers);
|
|
13254
|
+
let positionsUpserted = 0;
|
|
13255
|
+
let transfersInserted = 0;
|
|
12850
13256
|
if (resolvedTransfers.length > 0) {
|
|
12851
|
-
await dbTx.positions.upsert(positionsUpsert);
|
|
12852
|
-
await dbTx.transfers.create(resolvedTransfers);
|
|
13257
|
+
positionsUpserted = await dbTx.positions.upsert(positionsUpsert);
|
|
13258
|
+
transfersInserted = await dbTx.transfers.create(resolvedTransfers);
|
|
12853
13259
|
await recomputeBackfilledCollateralBalances({
|
|
12854
13260
|
dbTx,
|
|
12855
13261
|
transfers: resolvedTransfers
|
|
@@ -12858,7 +13264,9 @@ async function materializeSeizureFacts(parameters) {
|
|
|
12858
13264
|
return {
|
|
12859
13265
|
unresolvedFacts,
|
|
12860
13266
|
transfersCreate: resolvedTransfers,
|
|
12861
|
-
positionsUpsert
|
|
13267
|
+
positionsUpsert,
|
|
13268
|
+
transfersInserted,
|
|
13269
|
+
positionsUpserted
|
|
12862
13270
|
};
|
|
12863
13271
|
}
|
|
12864
13272
|
const toFactsFromPendingRows = (chainId, rows) => rows.map((row) => ({
|
|
@@ -13108,15 +13516,20 @@ const createPendingLinkStore = (parameters) => {
|
|
|
13108
13516
|
const resolverTypes = resolverEntries.map((resolver) => resolver.type);
|
|
13109
13517
|
return {
|
|
13110
13518
|
applySeizureFacts: async ({ dbTx, seizureFacts }) => {
|
|
13519
|
+
const materialized = await materializeSeizureFacts({
|
|
13520
|
+
dbTx,
|
|
13521
|
+
chainId,
|
|
13522
|
+
seizureFacts
|
|
13523
|
+
});
|
|
13111
13524
|
await recordUnresolvedSeizures({
|
|
13112
13525
|
dbTx,
|
|
13113
13526
|
chainId,
|
|
13114
|
-
seizureFacts:
|
|
13115
|
-
dbTx,
|
|
13116
|
-
chainId,
|
|
13117
|
-
seizureFacts
|
|
13118
|
-
})).unresolvedFacts
|
|
13527
|
+
seizureFacts: materialized.unresolvedFacts
|
|
13119
13528
|
});
|
|
13529
|
+
return {
|
|
13530
|
+
positionsUpserted: materialized.positionsUpserted,
|
|
13531
|
+
transfersInserted: materialized.transfersInserted
|
|
13532
|
+
};
|
|
13120
13533
|
},
|
|
13121
13534
|
recordIgnoredLinks: async ({ dbTx, records }) => {
|
|
13122
13535
|
if (records.length === 0) return;
|
|
@@ -13465,6 +13878,7 @@ const create$11 = (parameters) => {
|
|
|
13465
13878
|
chainMutationState
|
|
13466
13879
|
};
|
|
13467
13880
|
const commitAppliedStats = [];
|
|
13881
|
+
const commitAppliedDbRows = [];
|
|
13468
13882
|
const collectorsInCommit = /* @__PURE__ */ new Set();
|
|
13469
13883
|
const dispatchMutation = async (parameters) => {
|
|
13470
13884
|
const applier = mutationAppliers[parameters.mutation.t];
|
|
@@ -13477,18 +13891,24 @@ const create$11 = (parameters) => {
|
|
|
13477
13891
|
try {
|
|
13478
13892
|
await db.transaction(async (dbTx) => {
|
|
13479
13893
|
for (const mutation of tx.muts) {
|
|
13480
|
-
const
|
|
13894
|
+
const mutationApplyOutcome = await dispatchMutation({
|
|
13481
13895
|
mutation,
|
|
13482
13896
|
dbTx
|
|
13483
13897
|
});
|
|
13484
13898
|
if (mutation.collector === void 0) continue;
|
|
13485
13899
|
collectorsInCommit.add(mutation.collector);
|
|
13486
|
-
for (const stat of
|
|
13900
|
+
for (const stat of mutationApplyOutcome.stats) commitAppliedStats.push({
|
|
13487
13901
|
collector: mutation.collector,
|
|
13488
13902
|
entity: stat.entity,
|
|
13489
13903
|
operation: stat.operation,
|
|
13490
13904
|
count: stat.count
|
|
13491
13905
|
});
|
|
13906
|
+
for (const dbRow of mutationApplyOutcome.dbRows) commitAppliedDbRows.push({
|
|
13907
|
+
collector: mutation.collector,
|
|
13908
|
+
table: dbRow.table,
|
|
13909
|
+
operation: dbRow.operation,
|
|
13910
|
+
count: dbRow.count
|
|
13911
|
+
});
|
|
13492
13912
|
}
|
|
13493
13913
|
});
|
|
13494
13914
|
} catch (error) {
|
|
@@ -13503,6 +13923,7 @@ const create$11 = (parameters) => {
|
|
|
13503
13923
|
chainId,
|
|
13504
13924
|
collectors: [...collectorsInCommit],
|
|
13505
13925
|
stats: commitAppliedStats,
|
|
13926
|
+
dbRows: commitAppliedDbRows,
|
|
13506
13927
|
onCommitApplied
|
|
13507
13928
|
});
|
|
13508
13929
|
const nowBlock = state.chain.checkpoints[state.chain.checkpoints.length - 1]?.n ?? 0;
|
|
@@ -13550,19 +13971,21 @@ const create$11 = (parameters) => {
|
|
|
13550
13971
|
function emitCommitAppliedObservation(parameters) {
|
|
13551
13972
|
if (parameters.collectors.length === 0) return;
|
|
13552
13973
|
const aggregatedStats = aggregateCommitAppliedStats(parameters.stats);
|
|
13974
|
+
const aggregatedDbRows = aggregateCommitAppliedDbRows(parameters.dbRows);
|
|
13553
13975
|
try {
|
|
13554
13976
|
parameters.onCommitApplied({
|
|
13555
13977
|
chainId: parameters.chainId,
|
|
13556
13978
|
collectors: parameters.collectors,
|
|
13557
13979
|
committedAtUnixMs: Date.now(),
|
|
13558
|
-
stats: aggregatedStats
|
|
13980
|
+
stats: aggregatedStats,
|
|
13981
|
+
dbRows: aggregatedDbRows
|
|
13559
13982
|
});
|
|
13560
13983
|
} catch {}
|
|
13561
13984
|
}
|
|
13562
13985
|
function aggregateCommitAppliedStats(stats) {
|
|
13563
13986
|
const aggregatedByKey = /* @__PURE__ */ new Map();
|
|
13564
13987
|
for (const stat of stats) {
|
|
13565
|
-
const count =
|
|
13988
|
+
const count = normalizePositiveCount(stat.count);
|
|
13566
13989
|
if (count === null) continue;
|
|
13567
13990
|
const key = `${stat.collector}\u0000${stat.entity}\u0000${stat.operation}`;
|
|
13568
13991
|
const previous = aggregatedByKey.get(key);
|
|
@@ -13583,7 +14006,31 @@ function aggregateCommitAppliedStats(stats) {
|
|
|
13583
14006
|
return left.operation.localeCompare(right.operation);
|
|
13584
14007
|
});
|
|
13585
14008
|
}
|
|
13586
|
-
function
|
|
14009
|
+
function aggregateCommitAppliedDbRows(dbRows) {
|
|
14010
|
+
const aggregatedByKey = /* @__PURE__ */ new Map();
|
|
14011
|
+
for (const dbRow of dbRows) {
|
|
14012
|
+
const count = normalizePositiveCount(dbRow.count);
|
|
14013
|
+
if (count === null) continue;
|
|
14014
|
+
const key = `${dbRow.collector}\u0000${dbRow.table}\u0000${dbRow.operation}`;
|
|
14015
|
+
const previous = aggregatedByKey.get(key);
|
|
14016
|
+
if (previous === void 0) {
|
|
14017
|
+
aggregatedByKey.set(key, {
|
|
14018
|
+
collector: dbRow.collector,
|
|
14019
|
+
table: dbRow.table,
|
|
14020
|
+
operation: dbRow.operation,
|
|
14021
|
+
count
|
|
14022
|
+
});
|
|
14023
|
+
continue;
|
|
14024
|
+
}
|
|
14025
|
+
previous.count += count;
|
|
14026
|
+
}
|
|
14027
|
+
return [...aggregatedByKey.values()].sort((left, right) => {
|
|
14028
|
+
if (left.collector !== right.collector) return left.collector.localeCompare(right.collector);
|
|
14029
|
+
if (left.table !== right.table) return left.table.localeCompare(right.table);
|
|
14030
|
+
return left.operation.localeCompare(right.operation);
|
|
14031
|
+
});
|
|
14032
|
+
}
|
|
14033
|
+
function normalizePositiveCount(value) {
|
|
13587
14034
|
if (!Number.isFinite(value)) return null;
|
|
13588
14035
|
const normalized = Math.trunc(value);
|
|
13589
14036
|
return normalized > 0 ? normalized : null;
|
|
@@ -13813,7 +14260,7 @@ function processConsumedLogs(parameters) {
|
|
|
13813
14260
|
* A debt is modeled as a negative position: borrowing = transfer FROM user TO zeroAddress,
|
|
13814
14261
|
* repayment = FROM zeroAddress TO user. The contract field is the obligationId.
|
|
13815
14262
|
*
|
|
13816
|
-
* **Take event** — Every take is bilateral when
|
|
14263
|
+
* **Take event** — Every take is bilateral when units > 0:
|
|
13817
14264
|
* - Buyer (maker if offerIsBuy, taker otherwise): debt decreases (repaid) → from: 0x0 → to: buyer
|
|
13818
14265
|
* - Seller (taker if offerIsBuy, maker otherwise): debt increases (borrows) → from: seller → to: 0x0
|
|
13819
14266
|
*
|
|
@@ -13845,14 +14292,14 @@ function processDebtTransfers(parameters) {
|
|
|
13845
14292
|
if (eventName === takeEvent.name) {
|
|
13846
14293
|
const args = rawLog.args;
|
|
13847
14294
|
const obligationId = args?.id_;
|
|
13848
|
-
if (obligationId === void 0 || args?.maker === void 0 || args?.taker === void 0 || args?.offerIsBuy === void 0 || args?.
|
|
14295
|
+
if (obligationId === void 0 || args?.maker === void 0 || args?.taker === void 0 || args?.offerIsBuy === void 0 || args?.units === void 0) {
|
|
13849
14296
|
logger.debug({
|
|
13850
14297
|
event: INDEXER_COLLECTOR_LOG_SKIPPED,
|
|
13851
14298
|
msg: "Skipping Take log because it is missing required args for debt"
|
|
13852
14299
|
});
|
|
13853
14300
|
continue;
|
|
13854
14301
|
}
|
|
13855
|
-
if (args.
|
|
14302
|
+
if (args.units === 0n) continue;
|
|
13856
14303
|
const buyer = args.offerIsBuy ? args.maker : args.taker;
|
|
13857
14304
|
const seller = args.offerIsBuy ? args.taker : args.maker;
|
|
13858
14305
|
const blockNumber = Number(rawLog.blockNumber);
|
|
@@ -13862,7 +14309,7 @@ function processDebtTransfers(parameters) {
|
|
|
13862
14309
|
contract: obligationId,
|
|
13863
14310
|
from: zeroAddress,
|
|
13864
14311
|
to: buyer,
|
|
13865
|
-
value: args.
|
|
14312
|
+
value: args.units,
|
|
13866
14313
|
type: Type.DEBT_OF,
|
|
13867
14314
|
asset: zeroAddress,
|
|
13868
14315
|
blockNumber
|
|
@@ -13873,7 +14320,7 @@ function processDebtTransfers(parameters) {
|
|
|
13873
14320
|
contract: obligationId,
|
|
13874
14321
|
from: seller,
|
|
13875
14322
|
to: zeroAddress,
|
|
13876
|
-
value: args.
|
|
14323
|
+
value: args.units,
|
|
13877
14324
|
type: Type.DEBT_OF,
|
|
13878
14325
|
asset: zeroAddress,
|
|
13879
14326
|
blockNumber
|
|
@@ -13883,21 +14330,21 @@ function processDebtTransfers(parameters) {
|
|
|
13883
14330
|
if (eventName === repayEvent.name) {
|
|
13884
14331
|
const args = rawLog.args;
|
|
13885
14332
|
const obligationId = args?.id_;
|
|
13886
|
-
if (obligationId === void 0 || args?.
|
|
14333
|
+
if (obligationId === void 0 || args?.units === void 0 || args?.onBehalf === void 0) {
|
|
13887
14334
|
logger.debug({
|
|
13888
14335
|
event: INDEXER_COLLECTOR_LOG_SKIPPED,
|
|
13889
14336
|
msg: "Skipping Repay log because it is missing required args"
|
|
13890
14337
|
});
|
|
13891
14338
|
continue;
|
|
13892
14339
|
}
|
|
13893
|
-
if (args.
|
|
14340
|
+
if (args.units === 0n) continue;
|
|
13894
14341
|
transfers.push(from$7({
|
|
13895
14342
|
id: `${baseId}-debt-repay`,
|
|
13896
14343
|
chainId,
|
|
13897
14344
|
contract: obligationId,
|
|
13898
14345
|
from: zeroAddress,
|
|
13899
14346
|
to: args.onBehalf,
|
|
13900
|
-
value: args.
|
|
14347
|
+
value: args.units,
|
|
13901
14348
|
type: Type.DEBT_OF,
|
|
13902
14349
|
asset: zeroAddress,
|
|
13903
14350
|
blockNumber: Number(rawLog.blockNumber)
|
|
@@ -14221,6 +14668,15 @@ const processBatchesUntilCursorAdvance = async (stream, cursor, processBatch, op
|
|
|
14221
14668
|
const collectorName$7 = "morpho_v2";
|
|
14222
14669
|
const RESOLVE_CONSUMED_YIELD_EVERY_ITEMS = 256;
|
|
14223
14670
|
const RESOLVE_CONSUMED_YIELD_EVERY_MS = 8;
|
|
14671
|
+
const MORPHO_DERIVED_LOG_ID_SUFFIXES = [
|
|
14672
|
+
"-debt-buyer",
|
|
14673
|
+
"-debt-seller",
|
|
14674
|
+
"-debt-repay",
|
|
14675
|
+
"-debt-liquidate",
|
|
14676
|
+
"-collateral-supply",
|
|
14677
|
+
"-collateral-withdraw",
|
|
14678
|
+
"-collateral-liquidate"
|
|
14679
|
+
];
|
|
14224
14680
|
const runNativeStep$2 = async (parameters) => {
|
|
14225
14681
|
const { request, client, db, logger } = parameters;
|
|
14226
14682
|
const consumedEvents = [];
|
|
@@ -14228,7 +14684,6 @@ const runNativeStep$2 = async (parameters) => {
|
|
|
14228
14684
|
const collateralTransfers = [];
|
|
14229
14685
|
const seizureFacts = [];
|
|
14230
14686
|
let logsIngestedCount = 0;
|
|
14231
|
-
let logsIndexedCount = 0;
|
|
14232
14687
|
const streamStep = await processBatchesUntilCursorAdvance(streamLogs({
|
|
14233
14688
|
client,
|
|
14234
14689
|
contractAddress: client.chain.custom.morpho.address,
|
|
@@ -14253,7 +14708,13 @@ const runNativeStep$2 = async (parameters) => {
|
|
|
14253
14708
|
logs,
|
|
14254
14709
|
strict: false
|
|
14255
14710
|
});
|
|
14256
|
-
|
|
14711
|
+
const untrackedLogsCount = logs.length - parsedLogs.length;
|
|
14712
|
+
if (untrackedLogsCount > 0) logger.debug({
|
|
14713
|
+
event: INDEXER_COLLECTOR_LOG_SKIPPED,
|
|
14714
|
+
msg: "Skipping logs because they do not match tracked Morpho V2 events",
|
|
14715
|
+
reason: "untracked_event",
|
|
14716
|
+
count: untrackedLogsCount
|
|
14717
|
+
});
|
|
14257
14718
|
consumedEvents.push(...processConsumedLogs({
|
|
14258
14719
|
logs: parsedLogs,
|
|
14259
14720
|
chainId: client.chain.id
|
|
@@ -14282,14 +14743,21 @@ const runNativeStep$2 = async (parameters) => {
|
|
|
14282
14743
|
logsIndexedCount: 0
|
|
14283
14744
|
};
|
|
14284
14745
|
const { nextCursor } = streamStep;
|
|
14746
|
+
const resolvedConsumedEvents = await resolveConsumedEvents({
|
|
14747
|
+
db,
|
|
14748
|
+
consumedEvents,
|
|
14749
|
+
logger
|
|
14750
|
+
});
|
|
14751
|
+
const logsIndexedCount = countIndexedMorphoLogs({
|
|
14752
|
+
consumedEvents: resolvedConsumedEvents,
|
|
14753
|
+
debtTransfers,
|
|
14754
|
+
collateralTransfers,
|
|
14755
|
+
seizureFacts
|
|
14756
|
+
});
|
|
14285
14757
|
const domainMutations = buildDomainMutations$1({
|
|
14286
14758
|
debtTransfers,
|
|
14287
14759
|
collateralTransfers,
|
|
14288
|
-
consumedEvents:
|
|
14289
|
-
db,
|
|
14290
|
-
consumedEvents,
|
|
14291
|
-
logger
|
|
14292
|
-
}),
|
|
14760
|
+
consumedEvents: resolvedConsumedEvents,
|
|
14293
14761
|
seizureFacts
|
|
14294
14762
|
});
|
|
14295
14763
|
return {
|
|
@@ -14325,6 +14793,18 @@ const create$10 = (parameters) => {
|
|
|
14325
14793
|
});
|
|
14326
14794
|
};
|
|
14327
14795
|
};
|
|
14796
|
+
function countIndexedMorphoLogs(parameters) {
|
|
14797
|
+
const indexedLogIds = /* @__PURE__ */ new Set();
|
|
14798
|
+
for (const consumedEvent of parameters.consumedEvents) indexedLogIds.add(consumedEvent.id);
|
|
14799
|
+
for (const transfer of parameters.debtTransfers) indexedLogIds.add(stripMorphoDerivedLogIdSuffix(transfer.id));
|
|
14800
|
+
for (const transfer of parameters.collateralTransfers) indexedLogIds.add(stripMorphoDerivedLogIdSuffix(transfer.id));
|
|
14801
|
+
for (const seizureFact of parameters.seizureFacts) indexedLogIds.add(stripMorphoDerivedLogIdSuffix(seizureFact.id));
|
|
14802
|
+
return indexedLogIds.size;
|
|
14803
|
+
}
|
|
14804
|
+
function stripMorphoDerivedLogIdSuffix(id) {
|
|
14805
|
+
for (const suffix of MORPHO_DERIVED_LOG_ID_SUFFIXES) if (id.endsWith(suffix)) return id.slice(0, -suffix.length);
|
|
14806
|
+
return id;
|
|
14807
|
+
}
|
|
14328
14808
|
async function resolveConsumedEvents(parameters) {
|
|
14329
14809
|
const { db, consumedEvents, logger } = parameters;
|
|
14330
14810
|
if (consumedEvents.length === 0) return [];
|
|
@@ -14580,7 +15060,7 @@ const decodeCallbacks = (parameters) => {
|
|
|
14580
15060
|
if (!isEmptyCallback(offer)) continue;
|
|
14581
15061
|
if (offer.buy) {
|
|
14582
15062
|
const loanToken = offer.loanToken.toLowerCase();
|
|
14583
|
-
const positionTypeId$
|
|
15063
|
+
const positionTypeId$2 = positionTypeId(Type.ERC20);
|
|
14584
15064
|
positions.push(from$9({
|
|
14585
15065
|
chainId,
|
|
14586
15066
|
contract: loanToken,
|
|
@@ -14593,10 +15073,10 @@ const decodeCallbacks = (parameters) => {
|
|
|
14593
15073
|
positionChainId: chainId,
|
|
14594
15074
|
positionContract: loanToken,
|
|
14595
15075
|
positionUser: offer.maker,
|
|
14596
|
-
positionTypeId: positionTypeId$
|
|
15076
|
+
positionTypeId: positionTypeId$2,
|
|
14597
15077
|
group: offer.group,
|
|
14598
15078
|
obligationId,
|
|
14599
|
-
size:
|
|
15079
|
+
size: unitsToAssets(offer.maxUnits, offer.tick, offer.buy)
|
|
14600
15080
|
});
|
|
14601
15081
|
callbacks.push({
|
|
14602
15082
|
offerHash: hash$1(offer),
|
|
@@ -14605,22 +15085,22 @@ const decodeCallbacks = (parameters) => {
|
|
|
14605
15085
|
chainId,
|
|
14606
15086
|
contract: loanToken,
|
|
14607
15087
|
user: offer.maker,
|
|
14608
|
-
positionTypeId: positionTypeId$
|
|
15088
|
+
positionTypeId: positionTypeId$2,
|
|
14609
15089
|
type: CallbackType.Empty
|
|
14610
15090
|
}]
|
|
14611
15091
|
});
|
|
14612
15092
|
continue;
|
|
14613
15093
|
}
|
|
14614
15094
|
const contract = obligationId;
|
|
14615
|
-
const positionTypeId$
|
|
15095
|
+
const positionTypeId$1 = positionTypeId(Type.COLLATERAL_OF);
|
|
14616
15096
|
lots.push({
|
|
14617
15097
|
positionChainId: chainId,
|
|
14618
15098
|
positionContract: contract,
|
|
14619
15099
|
positionUser: offer.maker,
|
|
14620
|
-
positionTypeId: positionTypeId$
|
|
15100
|
+
positionTypeId: positionTypeId$1,
|
|
14621
15101
|
group: offer.group,
|
|
14622
15102
|
obligationId,
|
|
14623
|
-
size:
|
|
15103
|
+
size: unitsToAssets(offer.maxUnits, offer.tick, offer.buy)
|
|
14624
15104
|
});
|
|
14625
15105
|
callbacks.push({
|
|
14626
15106
|
offerHash: hash$1(offer),
|
|
@@ -14629,7 +15109,7 @@ const decodeCallbacks = (parameters) => {
|
|
|
14629
15109
|
chainId,
|
|
14630
15110
|
contract,
|
|
14631
15111
|
user: offer.maker,
|
|
14632
|
-
positionTypeId: positionTypeId$
|
|
15112
|
+
positionTypeId: positionTypeId$1,
|
|
14633
15113
|
type: CallbackType.Empty
|
|
14634
15114
|
}]
|
|
14635
15115
|
});
|
|
@@ -15269,9 +15749,11 @@ const runNativeStep = async (parameters) => {
|
|
|
15269
15749
|
});
|
|
15270
15750
|
transfers.push(...stepTransfers.transfers);
|
|
15271
15751
|
logsIndexedCount += stepTransfers.transfers.length;
|
|
15272
|
-
|
|
15752
|
+
if (stepTransfers.skippedInvalidLogs > 0) logger.debug({
|
|
15273
15753
|
event: INDEXER_COLLECTOR_LOG_SKIPPED,
|
|
15274
|
-
msg: "Skipping
|
|
15754
|
+
msg: "Skipping transfer logs because they are missing required fields",
|
|
15755
|
+
reason: "missing_required_fields",
|
|
15756
|
+
count: stepTransfers.skippedInvalidLogs
|
|
15275
15757
|
});
|
|
15276
15758
|
if (shouldContinueStream({
|
|
15277
15759
|
pendingPositionsCount: pendingNewPositions.length,
|
|
@@ -16674,7 +17156,7 @@ const init = (parameters) => {
|
|
|
16674
17156
|
maker: item.offer.maker,
|
|
16675
17157
|
group: item.offer.group,
|
|
16676
17158
|
tick: item.offer.tick,
|
|
16677
|
-
|
|
17159
|
+
max_units: item.offer.maxUnits.toString(),
|
|
16678
17160
|
buy: item.offer.buy
|
|
16679
17161
|
});
|
|
16680
17162
|
}
|
|
@@ -17997,7 +18479,7 @@ function buildOfferAssociationsFromOffers(parameters) {
|
|
|
17997
18479
|
user: offer.maker,
|
|
17998
18480
|
type: Type.ERC20,
|
|
17999
18481
|
asset: loanToken,
|
|
18000
|
-
balance:
|
|
18482
|
+
balance: unitsToAssets(offer.maxUnits, offer.tick, true),
|
|
18001
18483
|
blockNumber
|
|
18002
18484
|
}));
|
|
18003
18485
|
callbacks.push({
|
|
@@ -18018,7 +18500,7 @@ function buildOfferAssociationsFromOffers(parameters) {
|
|
|
18018
18500
|
positionTypeId: erc20TypeId,
|
|
18019
18501
|
group: offer.group,
|
|
18020
18502
|
obligationId,
|
|
18021
|
-
size:
|
|
18503
|
+
size: unitsToAssets(offer.maxUnits, offer.tick, offer.buy)
|
|
18022
18504
|
});
|
|
18023
18505
|
}
|
|
18024
18506
|
return {
|
|
@@ -18146,7 +18628,8 @@ function createMockOffers(parameters) {
|
|
|
18146
18628
|
const collaterals = collateralSelections.map((asset) => from$13({
|
|
18147
18629
|
asset,
|
|
18148
18630
|
oracle: allowedOracles[int(allowedOracles.length)],
|
|
18149
|
-
lltv
|
|
18631
|
+
lltv,
|
|
18632
|
+
maxLif: 0n
|
|
18150
18633
|
}));
|
|
18151
18634
|
if (!chainRegistry.getById(chain.id)) throw new Error(`Missing chain config for id ${chain.id}`);
|
|
18152
18635
|
return {
|