@morpho-dev/router 0.7.0 → 0.7.2

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.
@@ -139,6 +139,61 @@ const MetaMorpho = (0, viem.parseAbi)([
139
139
  //#region src/core/Abi/MetaMorphoFactory.ts
140
140
  const MetaMorphoFactory = (0, viem.parseAbi)(["event CreateMetaMorpho(address indexed metaMorpho,address indexed caller,address initialOwner,uint256 initialTimelock,address indexed asset,string name,string symbol,bytes32 salt)", "function isMetaMorpho(address) view returns (bool)"]);
141
141
 
142
+ //#endregion
143
+ //#region src/core/Abi/MorphoV2.ts
144
+ const MorphoV2 = (0, viem.parseAbi)([
145
+ "constructor()",
146
+ "function collateralOf(bytes32 id, address user, address collateralToken) view returns (uint256)",
147
+ "function consume(bytes32 group, uint256 amount)",
148
+ "function consumed(address user, bytes32 group) view returns (uint256)",
149
+ "function debtOf(bytes32 id, address user) view returns (uint256)",
150
+ "function defaultFees(address loanToken, uint256 index) view returns (uint16)",
151
+ "function feeSetter() view returns (address)",
152
+ "function fees(bytes32 id) view returns (uint16[6])",
153
+ "function flashLoan(address token, uint256 assets, address callback, bytes data)",
154
+ "function isHealthy((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bytes32 id, address borrower) view returns (bool)",
155
+ "function liquidate((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, (uint256 collateralIndex, uint256 repaid, uint256 seized)[] seizures, address borrower, bytes data) returns ((uint256 collateralIndex, uint256 repaid, uint256 seized)[])",
156
+ "function multicall(bytes[] calls)",
157
+ "function obligationCreated(bytes32 id) view returns (bool)",
158
+ "function obligationState(bytes32 id) view returns (uint128 totalUnits, uint128 totalShares, uint256 withdrawable, bool created)",
159
+ "function owner() view returns (address)",
160
+ "function repay((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, address onBehalf)",
161
+ "function session(address user) view returns (bytes32)",
162
+ "function setDefaultTradingFee(address loanToken, uint256 index, uint256 newTradingFee)",
163
+ "function setFeeSetter(address newFeeSetter)",
164
+ "function setObligationTradingFee(bytes32 id, uint256 index, uint256 newTradingFee)",
165
+ "function setOwner(address newOwner)",
166
+ "function setTradingFeeRecipient(address recipient)",
167
+ "function sharesOf(bytes32 id, address user) view returns (uint256)",
168
+ "function shuffleSession()",
169
+ "function supplyCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, address collateral, uint256 assets, address onBehalf)",
170
+ "function take(uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, address taker, ((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, bool buy, address maker, uint256 assets, uint256 obligationUnits, uint256 obligationShares, uint256 start, uint256 expiry, uint256 tick, bytes32 group, bytes32 session, address callback, bytes callbackData) offer, (uint8 v, bytes32 r, bytes32 s) sig, bytes32 root, bytes32[] proof, address takerCallback, bytes takerCallbackData) returns (uint256, uint256, uint256, uint256)",
171
+ "function totalShares(bytes32 id) view returns (uint256)",
172
+ "function totalUnits(bytes32 id) view returns (uint256)",
173
+ "function touchObligation((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation) returns (bytes32)",
174
+ "function tradingFee(bytes32 id, uint256 timeToMaturity) view returns (uint256)",
175
+ "function tradingFeeRecipient() view returns (address)",
176
+ "function withdraw((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, uint256 obligationUnits, uint256 shares, address onBehalf) returns (uint256, uint256)",
177
+ "function withdrawCollateral((address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation, address collateral, uint256 assets, address onBehalf)",
178
+ "function withdrawable(bytes32 id) view returns (uint256)",
179
+ "event Constructor(address indexed owner)",
180
+ "event Consume(address indexed user, bytes32 indexed group, uint256 amount)",
181
+ "event FlashLoan(address indexed caller, address indexed token, uint256 assets)",
182
+ "event Liquidate(address indexed caller, bytes32 indexed id, (uint256 collateralIndex, uint256 repaid, uint256 seized)[] seizures, address indexed borrower, uint256 totalRepaid, uint256 badDebt)",
183
+ "event ObligationCreated(bytes32 indexed id, (address loanToken, (address token, uint256 lltv, address oracle)[] collaterals, uint256 maturity) obligation)",
184
+ "event Repay(address indexed caller, bytes32 indexed id, uint256 obligationUnits, address indexed onBehalf)",
185
+ "event SetDefaultTradingFee(address indexed loanToken, uint256 indexed index, uint256 newTradingFee)",
186
+ "event SetFeeSetter(address indexed feeSetter)",
187
+ "event SetObligationTradingFee(bytes32 indexed id, uint256 indexed index, uint256 newTradingFee)",
188
+ "event SetOwner(address indexed owner)",
189
+ "event SetTradingFeeRecipient(address indexed recipient)",
190
+ "event ShuffleSession(address indexed user, bytes32 session)",
191
+ "event SupplyCollateral(address caller, bytes32 indexed id, address indexed collateral, uint256 assets, address indexed onBehalf)",
192
+ "event Take(address caller, bytes32 indexed id, address indexed maker, address indexed taker, bool offerIsBuy, uint256 buyerAssets, uint256 sellerAssets, uint256 obligationUnits, uint256 obligationShares, bool buyerIsLender, bool sellerIsBorrower, bytes32 group, uint256 consumed)",
193
+ "event Withdraw(address indexed caller, bytes32 indexed id, uint256 obligationUnits, uint256 shares, address indexed onBehalf)",
194
+ "event WithdrawCollateral(address caller, bytes32 indexed id, address indexed collateral, uint256 assets, address indexed onBehalf)"
195
+ ]);
196
+
142
197
  //#endregion
143
198
  //#region src/core/Abi/index.ts
144
199
  var Abi_exports = /* @__PURE__ */ __exportAll({
@@ -146,6 +201,7 @@ var Abi_exports = /* @__PURE__ */ __exportAll({
146
201
  MetaMorpho: () => MetaMorpho,
147
202
  MetaMorphoFactory: () => MetaMorphoFactory,
148
203
  Morpho: () => Morpho,
204
+ MorphoV2: () => MorphoV2,
149
205
  Oracle: () => Oracle
150
206
  });
151
207
  const Oracle = [{
@@ -294,107 +350,14 @@ const Morpho = [
294
350
  //#region src/core/Callback.ts
295
351
  var Callback_exports = /* @__PURE__ */ __exportAll({
296
352
  Type: () => Type$1,
297
- decode: () => decode$2,
298
- decodeBuyERC20: () => decodeBuyERC20,
299
- decodeBuyVaultV1Callback: () => decodeBuyVaultV1Callback,
300
- decodeSellERC20Callback: () => decodeSellERC20Callback,
301
- encode: () => encode$2,
302
- encodeBuyERC20: () => encodeBuyERC20,
303
- encodeBuyVaultV1Callback: () => encodeBuyVaultV1Callback,
304
- encodeSellERC20Callback: () => encodeSellERC20Callback,
305
353
  isEmptyCallback: () => isEmptyCallback
306
354
  });
307
355
  let Type$1 = /* @__PURE__ */ function(Type) {
308
356
  Type["BuyWithEmptyCallback"] = "buy_with_empty_callback";
309
- Type["BuyERC20"] = "buy_erc20";
310
- Type["BuyVaultV1Callback"] = "buy_vault_v1_callback";
311
- Type["SellERC20Callback"] = "sell_erc20_callback";
357
+ Type["SellWithEmptyCallback"] = "sell_with_empty_callback";
312
358
  return Type;
313
359
  }({});
314
360
  const isEmptyCallback = (offer) => offer.callback.data === "0x";
315
- function decode$2(type, data) {
316
- switch (type) {
317
- case Type$1.BuyERC20: return decodeBuyERC20(data);
318
- case Type$1.BuyVaultV1Callback: return decodeBuyVaultV1Callback(data);
319
- case Type$1.SellERC20Callback: return decodeSellERC20Callback(data);
320
- default: throw new Error("Invalid callback type");
321
- }
322
- }
323
- function encode$2(type, data) {
324
- switch (type) {
325
- case Type$1.BuyERC20:
326
- if (!("tokens" in data)) throw new Error("Invalid callback data");
327
- return encodeBuyERC20(data);
328
- case Type$1.BuyVaultV1Callback:
329
- if (!("vaults" in data)) throw new Error("Invalid callback data");
330
- return encodeBuyVaultV1Callback(data);
331
- case Type$1.SellERC20Callback:
332
- if (!("collaterals" in data)) throw new Error("Invalid callback data");
333
- return encodeSellERC20Callback(data);
334
- default: throw new Error("Invalid callback type");
335
- }
336
- }
337
- /**
338
- * Decodes BuyERC20 callback data into positions.
339
- * @param data - The ABI-encoded callback data containing token addresses and amounts.
340
- * @returns Array of positions with contract address and amount.
341
- * @throws If data is empty, malformed, or arrays have mismatched lengths.
342
- */
343
- function decodeBuyERC20(data) {
344
- if (!data || data === "0x") throw new Error("Empty callback data");
345
- let tokens;
346
- let amounts;
347
- try {
348
- [tokens, amounts] = (0, viem.decodeAbiParameters)([{ type: "address[]" }, { type: "uint256[]" }], data);
349
- } catch (_) {
350
- throw new Error("Invalid BuyERC20 callback data");
351
- }
352
- if (tokens.length !== amounts.length) throw new Error("Mismatched array lengths");
353
- return tokens.map((token, index) => ({
354
- contract: token,
355
- amount: amounts[index]
356
- }));
357
- }
358
- /**
359
- * Encodes BuyERC20 callback parameters into ABI-encoded data.
360
- * @param parameters - The tokens and amounts to encode.
361
- * @returns ABI-encoded hex string.
362
- */
363
- function encodeBuyERC20(parameters) {
364
- return (0, viem.encodeAbiParameters)([{ type: "address[]" }, { type: "uint256[]" }], [parameters.tokens, parameters.amounts]);
365
- }
366
- function decodeBuyVaultV1Callback(data) {
367
- if (!data || data === "0x") throw new Error("Empty callback data");
368
- try {
369
- const [vaults, amounts] = (0, viem.decodeAbiParameters)([{ type: "address[]" }, { type: "uint256[]" }], data);
370
- if (vaults.length !== amounts.length) throw new Error("Mismatched array lengths");
371
- return vaults.map((v, i) => ({
372
- contract: v,
373
- amount: amounts[i]
374
- }));
375
- } catch (_) {
376
- throw new Error("Invalid BuyVaultV1Callback callback data");
377
- }
378
- }
379
- function decodeSellERC20Callback(data) {
380
- if (!data || data === "0x") throw new Error("Empty callback data");
381
- try {
382
- const [collaterals, amounts] = (0, viem.decodeAbiParameters)([{ type: "address[]" }, { type: "uint256[]" }], data);
383
- if (collaterals.length !== amounts.length) throw new Error("Mismatched array lengths");
384
- return collaterals.map((c, i) => ({
385
- contract: c,
386
- amount: amounts[i]
387
- }));
388
- } catch (_) {
389
- throw new Error("Invalid SellERC20Callback callback data");
390
- }
391
- }
392
- function encodeBuyVaultV1Callback(parameters) {
393
- return (0, viem.encodeAbiParameters)([{ type: "address[]" }, { type: "uint256[]" }], [parameters.vaults, parameters.amounts]);
394
- }
395
- function encodeSellERC20Callback(parameters) {
396
- return (0, viem.encodeAbiParameters)([{ type: "address[]" }, { type: "uint256[]" }], [parameters.collaterals, parameters.amounts]);
397
- }
398
361
 
399
362
  //#endregion
400
363
  //#region src/utils/BigMath.ts
@@ -644,8 +607,8 @@ const chains$1 = {
644
607
  name: "ethereum-virtual-testnet",
645
608
  custom: {
646
609
  morpho: {
647
- address: "0x11a002d45db720ed47a80d2f3489cba5b833eaf5",
648
- blockCreated: 0
610
+ address: "0x634b095371e4e45feed94c1a45c37798e173ea50",
611
+ blockCreated: 23226700
649
612
  },
650
613
  morphoBlue: {
651
614
  address: "0xBBBBBbbBBb9cC5e90e3b3Af64bdAF62C37EEFFCb",
@@ -1150,11 +1113,9 @@ var Liquidity_exports = /* @__PURE__ */ __exportAll({
1150
1113
  calculateMaxDebt: () => calculateMaxDebt,
1151
1114
  generateAllowancePoolId: () => generateAllowancePoolId,
1152
1115
  generateBalancePoolId: () => generateBalancePoolId,
1153
- generateBuyVaultCallbackPoolId: () => generateBuyVaultCallbackPoolId,
1154
1116
  generateDebtPoolId: () => generateDebtPoolId,
1155
1117
  generateMarketLiquidityPoolId: () => generateMarketLiquidityPoolId,
1156
1118
  generateObligationCollateralPoolId: () => generateObligationCollateralPoolId,
1157
- generateSellERC20CallbackPoolId: () => generateSellERC20CallbackPoolId,
1158
1119
  generateUserVaultPositionPoolId: () => generateUserVaultPositionPoolId,
1159
1120
  generateVaultPositionPoolId: () => generateVaultPositionPoolId
1160
1121
  });
@@ -1183,14 +1144,6 @@ function generateAllowancePoolId(parameters) {
1183
1144
  return `${user}-${chainId.toString()}-${token}-allowance`.toLowerCase();
1184
1145
  }
1185
1146
  /**
1186
- * Generate pool ID for sell ERC20 callback pools.
1187
- * Each offer has its own callback pool to prevent liquidity conflicts.
1188
- */
1189
- function generateSellERC20CallbackPoolId(parameters) {
1190
- const { user, chainId, obligationId, token, offerHash } = parameters;
1191
- return `${user}-${chainId.toString()}-${obligationId}-${token}-${offerHash}-sell_erc20_callback`.toLowerCase();
1192
- }
1193
- /**
1194
1147
  * Generate pool ID for obligation collateral pools.
1195
1148
  * Obligation collateral pools represent collateral already deposited in the obligation.
1196
1149
  * These pools are shared across all offers with the same obligation.
@@ -1200,13 +1153,6 @@ function generateObligationCollateralPoolId(parameters) {
1200
1153
  return `${user}-${chainId.toString()}-${obligationId}-${token}-obligation-collateral`.toLowerCase();
1201
1154
  }
1202
1155
  /**
1203
- * Generate pool ID for buy vault callback pools.
1204
- */
1205
- function generateBuyVaultCallbackPoolId(parameters) {
1206
- const { user, chainId, vault, offerHash } = parameters;
1207
- return `${user}-${chainId.toString()}-${vault}-${offerHash}-${Type$1.BuyVaultV1Callback}`.toLowerCase();
1208
- }
1209
- /**
1210
1156
  * Generate pool ID for debt pools.
1211
1157
  */
1212
1158
  function generateDebtPoolId(parameters) {
@@ -1586,6 +1532,7 @@ var Offer_exports = /* @__PURE__ */ __exportAll({
1586
1532
  obligationId: () => obligationId,
1587
1533
  random: () => random$1,
1588
1534
  serialize: () => serialize,
1535
+ takeEvent: () => takeEvent,
1589
1536
  toSnakeCase: () => toSnakeCase,
1590
1537
  types: () => types
1591
1538
  });
@@ -1704,7 +1651,7 @@ function random$1(config) {
1704
1651
  const chain = config?.chains ? config.chains[int(config.chains.length)] : chains$1.ethereum;
1705
1652
  const loanToken = config?.loanTokens ? config.loanTokens[int(config.loanTokens.length)] : address();
1706
1653
  const collateralCandidates = config?.collateralTokens ? config.collateralTokens.filter((a) => a !== loanToken) : [address()];
1707
- const collateralAsset = collateralCandidates[int(collateralCandidates.length)];
1654
+ collateralCandidates[int(collateralCandidates.length)];
1708
1655
  const maturityOption = weightedChoice([["end_of_month", 1], ["end_of_next_month", 1]]);
1709
1656
  const maturity = config?.maturity ?? from$11(maturityOption);
1710
1657
  const lltv = from$13(weightedChoice([
@@ -1731,21 +1678,10 @@ function random$1(config) {
1731
1678
  const unit = BigInt(10) ** BigInt(loanTokenDecimals);
1732
1679
  const amountBase = BigInt(100 + int(999901));
1733
1680
  const assetsScaled = config?.assets ?? amountBase * unit;
1734
- const callbackBySide = (() => {
1735
- if (buy) return {
1736
- address: viem.zeroAddress,
1737
- data: "0x"
1738
- };
1739
- const sellCallbackAddress = "0x3333333333333333333333333333333333333333";
1740
- const amount = assetsScaled * 1000000000000000000000n;
1741
- return {
1742
- address: sellCallbackAddress,
1743
- data: encodeSellERC20Callback({
1744
- collaterals: [collateralAsset],
1745
- amounts: [amount]
1746
- })
1747
- };
1748
- })();
1681
+ const emptyCallback = {
1682
+ address: viem.zeroAddress,
1683
+ data: "0x"
1684
+ };
1749
1685
  return from$9({
1750
1686
  maker: config?.maker ?? address(),
1751
1687
  assets: assetsScaled,
@@ -1764,7 +1700,7 @@ function random$1(config) {
1764
1700
  ...random$3(),
1765
1701
  lltv
1766
1702
  })).sort((a, b) => a.asset.localeCompare(b.asset)),
1767
- callback: config?.callback ?? callbackBySide
1703
+ callback: config?.callback ?? emptyCallback
1768
1704
  });
1769
1705
  }
1770
1706
  const weightedChoice = (pairs) => {
@@ -2054,6 +1990,94 @@ function decode$1(data) {
2054
1990
  });
2055
1991
  }
2056
1992
  /**
1993
+ * ABI for the Take event emitted by the Morpho V2 contract.
1994
+ */
1995
+ const takeEvent = {
1996
+ type: "event",
1997
+ name: "Take",
1998
+ inputs: [
1999
+ {
2000
+ name: "caller",
2001
+ type: "address",
2002
+ indexed: false,
2003
+ internalType: "address"
2004
+ },
2005
+ {
2006
+ name: "id",
2007
+ type: "bytes32",
2008
+ indexed: true,
2009
+ internalType: "bytes32"
2010
+ },
2011
+ {
2012
+ name: "maker",
2013
+ type: "address",
2014
+ indexed: true,
2015
+ internalType: "address"
2016
+ },
2017
+ {
2018
+ name: "taker",
2019
+ type: "address",
2020
+ indexed: true,
2021
+ internalType: "address"
2022
+ },
2023
+ {
2024
+ name: "offerIsBuy",
2025
+ type: "bool",
2026
+ indexed: false,
2027
+ internalType: "bool"
2028
+ },
2029
+ {
2030
+ name: "buyerAssets",
2031
+ type: "uint256",
2032
+ indexed: false,
2033
+ internalType: "uint256"
2034
+ },
2035
+ {
2036
+ name: "sellerAssets",
2037
+ type: "uint256",
2038
+ indexed: false,
2039
+ internalType: "uint256"
2040
+ },
2041
+ {
2042
+ name: "obligationUnits",
2043
+ type: "uint256",
2044
+ indexed: false,
2045
+ internalType: "uint256"
2046
+ },
2047
+ {
2048
+ name: "obligationShares",
2049
+ type: "uint256",
2050
+ indexed: false,
2051
+ internalType: "uint256"
2052
+ },
2053
+ {
2054
+ name: "buyerIsLender",
2055
+ type: "bool",
2056
+ indexed: false,
2057
+ internalType: "bool"
2058
+ },
2059
+ {
2060
+ name: "sellerIsBorrower",
2061
+ type: "bool",
2062
+ indexed: false,
2063
+ internalType: "bool"
2064
+ },
2065
+ {
2066
+ name: "group",
2067
+ type: "bytes32",
2068
+ indexed: false,
2069
+ internalType: "bytes32"
2070
+ },
2071
+ {
2072
+ name: "consumed",
2073
+ type: "uint256",
2074
+ indexed: false,
2075
+ internalType: "uint256"
2076
+ }
2077
+ ],
2078
+ anonymous: false
2079
+ };
2080
+ /**
2057
2081
  * ABI for the Consume event emitted by the Obligation contract.
2058
2082
  */
2059
2083
  const consumedEvent = {
@@ -2807,6 +2831,16 @@ const BrandTypeId = Symbol.for("mempool/Brand");
2807
2831
  //#endregion
2808
2832
  //#region src/api/Schema/OfferResponse.ts
2809
2833
  var OfferResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$2 });
2834
+ function normalizeChainId(chainId) {
2835
+ const parsedChainId = Number(chainId);
2836
+ if (!Number.isInteger(parsedChainId) || parsedChainId <= 0) throw new Error(`Invalid chain id: ${String(chainId)}`);
2837
+ return parsedChainId;
2838
+ }
2839
+ function normalizeBlockNumber(blockNumber) {
2840
+ const parsedBlockNumber = Number(blockNumber);
2841
+ if (!Number.isInteger(parsedBlockNumber) || parsedBlockNumber < 0) throw new Error(`Invalid block number: ${String(blockNumber)}`);
2842
+ return parsedBlockNumber;
2843
+ }
2810
2844
  /**
2811
2845
  * Creates an `OfferResponse` matching the Solidity Offer struct layout.
2812
2846
  * @constructor
@@ -2814,6 +2848,8 @@ var OfferResponse_exports = /* @__PURE__ */ __exportAll({ from: () => from$2 });
2814
2848
  * @returns The created `OfferResponse`. {@link OfferResponse}
2815
2849
  */
2816
2850
  function from$2(input) {
2851
+ const chainId = normalizeChainId(input.chainId);
2852
+ const blockNumber = normalizeBlockNumber(input.blockNumber);
2817
2853
  const base = {
2818
2854
  offer: {
2819
2855
  obligation: {
@@ -2840,15 +2876,15 @@ function from$2(input) {
2840
2876
  },
2841
2877
  offer_hash: input.hash,
2842
2878
  obligation_id: id({
2843
- chainId: input.chainId,
2879
+ chainId,
2844
2880
  loanToken: input.loanToken,
2845
2881
  collaterals: [...input.collaterals],
2846
2882
  maturity: input.maturity
2847
2883
  }),
2848
- chain_id: input.chainId,
2884
+ chain_id: chainId,
2849
2885
  consumed: input.consumed.toString(),
2850
2886
  takeable: input.takeable.toString(),
2851
- block_number: input.blockNumber
2887
+ block_number: blockNumber
2852
2888
  };
2853
2889
  if (!input.proof || !input.root || !input.signature) return {
2854
2890
  ...base,
@@ -2908,8 +2944,8 @@ const offerExample = {
2908
2944
  price: "2750000000000000000",
2909
2945
  group: "0x000000000000000000000000000000000000000000000000000000000008b8f4",
2910
2946
  session: "0x0000000000000000000000000000000000000000000000000000000000000000",
2911
- callback: "0x1111111111111111111111111111111111111111",
2912
- callback_data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
2947
+ callback: "0x0000000000000000000000000000000000000000",
2948
+ callback_data: "0x"
2913
2949
  },
2914
2950
  offer_hash: "0xac4bd8318ec914f89f8af913f162230575b0ac0696a19256bc12138c5cfe1427",
2915
2951
  obligation_id: "0x25690ae1aee324a005be565f3bcdd16dbf8daf7969b26c181c8b8f467dad9abc",
@@ -2961,25 +2997,10 @@ const validateOfferExample = {
2961
2997
  lltv: "860000000000000000"
2962
2998
  }],
2963
2999
  callback: {
2964
- address: "0x1111111111111111111111111111111111111111",
2965
- data: "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000100000000000000000000000034cf890db685fc536e05652fb41f02090c3fb751000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000108e644e3ab01184155270aa92a00000000000"
3000
+ address: "0x0000000000000000000000000000000000000000",
3001
+ data: "0x"
2966
3002
  }
2967
3003
  };
2968
- const callbackTypesRequestExample = { callbacks: [{
2969
- chain_id: 1,
2970
- addresses: [
2971
- "0x1111111111111111111111111111111111111111",
2972
- "0x3333333333333333333333333333333333333333",
2973
- "0x9999999999999999999999999999999999999999"
2974
- ]
2975
- }] };
2976
- const callbackTypesResponseExample = [{
2977
- chain_id: 1,
2978
- sell_erc20_callback: ["0x1111111111111111111111111111111111111111"],
2979
- buy_erc20: ["0x5555555555555555555555555555555555555555"],
2980
- buy_vault_v1_callback: ["0x3333333333333333333333333333333333333333"],
2981
- not_supported: ["0x9999999999999999999999999999999999999999"]
2982
- }];
2983
3004
  const routerStatusExample = {
2984
3005
  status: "live",
2985
3006
  initialized: true,
@@ -3048,55 +3069,6 @@ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3048
3069
  type: "string",
3049
3070
  example: validateOfferExample.callback.data
3050
3071
  })], ValidateCallbackRequest.prototype, "data", void 0);
3051
- var CallbackTypesChainRequest = class {};
3052
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3053
- type: "number",
3054
- example: callbackTypesRequestExample.callbacks[0].chain_id
3055
- })], CallbackTypesChainRequest.prototype, "chain_id", void 0);
3056
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3057
- type: () => [String],
3058
- example: callbackTypesRequestExample.callbacks[0].addresses
3059
- })], CallbackTypesChainRequest.prototype, "addresses", void 0);
3060
- var CallbackTypesRequest = class {};
3061
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3062
- type: () => [CallbackTypesChainRequest],
3063
- example: callbackTypesRequestExample.callbacks
3064
- })], CallbackTypesRequest.prototype, "callbacks", void 0);
3065
- var CallbackTypesChainResponse = class {};
3066
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3067
- type: "number",
3068
- example: callbackTypesResponseExample[0].chain_id
3069
- })], CallbackTypesChainResponse.prototype, "chain_id", void 0);
3070
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3071
- type: () => [String],
3072
- required: false,
3073
- example: callbackTypesResponseExample[0].buy_vault_v1_callback
3074
- })], CallbackTypesChainResponse.prototype, "buy_vault_v1_callback", void 0);
3075
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3076
- type: () => [String],
3077
- required: false,
3078
- example: callbackTypesResponseExample[0].sell_erc20_callback
3079
- })], CallbackTypesChainResponse.prototype, "sell_erc20_callback", void 0);
3080
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3081
- type: () => [String],
3082
- required: false,
3083
- example: callbackTypesResponseExample[0].buy_erc20
3084
- })], CallbackTypesChainResponse.prototype, "buy_erc20", void 0);
3085
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3086
- type: () => [String],
3087
- example: callbackTypesResponseExample[0].not_supported
3088
- })], CallbackTypesChainResponse.prototype, "not_supported", void 0);
3089
- var CallbackTypesSuccessResponse = class extends SuccessResponse {};
3090
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3091
- type: "string",
3092
- nullable: true,
3093
- example: "maturity:1:1730415600:end_of_next_month"
3094
- })], CallbackTypesSuccessResponse.prototype, "cursor", void 0);
3095
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3096
- type: () => [CallbackTypesChainResponse],
3097
- description: "Callback types grouped by chain.",
3098
- example: callbackTypesResponseExample
3099
- })], CallbackTypesSuccessResponse.prototype, "data", void 0);
3100
3072
  var AskResponse = class {};
3101
3073
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3102
3074
  type: "string",
@@ -3614,7 +3586,7 @@ __decorate([
3614
3586
  methods: ["post"],
3615
3587
  path: "/v1/validate",
3616
3588
  summary: "Validate offers",
3617
- description: "Validates offers against router validation rules. Returns unsigned payload + root on success, or issues only on validation failure."
3589
+ description: "Validates offers against router validation rules. Only empty callbacks (zero address, 0x data) are accepted. Returns unsigned payload + root on success, or issues only on validation failure."
3618
3590
  }),
3619
3591
  (0, openapi_metadata_decorators.ApiBody)({ type: ValidateOffersRequest }),
3620
3592
  (0, openapi_metadata_decorators.ApiResponse)({
@@ -3633,28 +3605,6 @@ ValidateController = __decorate([(0, openapi_metadata_decorators.ApiTags)("Make"
3633
3605
  description: "Bad Request",
3634
3606
  type: BadRequestResponse
3635
3607
  })], ValidateController);
3636
- let CallbacksController = class CallbacksController {
3637
- async resolveCallbackTypes() {}
3638
- };
3639
- __decorate([
3640
- (0, openapi_metadata_decorators.ApiOperation)({
3641
- methods: ["post"],
3642
- path: "/v1/callbacks",
3643
- summary: "Resolve callback types",
3644
- description: "Returns callback types for callback addresses grouped by chain."
3645
- }),
3646
- (0, openapi_metadata_decorators.ApiBody)({ type: CallbackTypesRequest }),
3647
- (0, openapi_metadata_decorators.ApiResponse)({
3648
- status: 200,
3649
- description: "Success",
3650
- type: CallbackTypesSuccessResponse
3651
- })
3652
- ], CallbacksController.prototype, "resolveCallbackTypes", null);
3653
- CallbacksController = __decorate([(0, openapi_metadata_decorators.ApiTags)("Make"), (0, openapi_metadata_decorators.ApiResponse)({
3654
- status: 400,
3655
- description: "Bad Request",
3656
- type: BadRequestResponse
3657
- })], CallbacksController);
3658
3608
  let OffersController = class OffersController {
3659
3609
  async getOffers() {}
3660
3610
  };
@@ -3804,12 +3754,6 @@ const configRulesMaturityExample = {
3804
3754
  name: "end_of_next_month",
3805
3755
  timestamp: 1730415600
3806
3756
  };
3807
- const configRulesCallbackExample = {
3808
- type: "callback",
3809
- chain_id: 1,
3810
- address: "0x1111111111111111111111111111111111111111",
3811
- callback_type: "sell_erc20_callback"
3812
- };
3813
3757
  const configRulesLoanTokenExample = {
3814
3758
  type: "loan_token",
3815
3759
  chain_id: 1,
@@ -3823,7 +3767,6 @@ const configRulesOracleExample = {
3823
3767
  const configRulesChecksumExample = "f1d2d2f924e986ac86fdf7b36c94bcdf";
3824
3768
  const configRulesPayloadExample = [
3825
3769
  configRulesMaturityExample,
3826
- configRulesCallbackExample,
3827
3770
  configRulesLoanTokenExample,
3828
3771
  configRulesOracleExample
3829
3772
  ];
@@ -3888,14 +3831,9 @@ __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3888
3831
  })], ConfigRulesRuleResponse.prototype, "timestamp", void 0);
3889
3832
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3890
3833
  type: "string",
3891
- example: configRulesCallbackExample.address,
3834
+ example: configRulesLoanTokenExample.address,
3892
3835
  required: false
3893
3836
  })], ConfigRulesRuleResponse.prototype, "address", void 0);
3894
- __decorate([(0, openapi_metadata_decorators.ApiProperty)({
3895
- type: "string",
3896
- example: configRulesCallbackExample.callback_type,
3897
- required: false
3898
- })], ConfigRulesRuleResponse.prototype, "callback_type", void 0);
3899
3837
  var ConfigRulesSuccessResponse = class {};
3900
3838
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({ type: () => ConfigRulesMeta })], ConfigRulesSuccessResponse.prototype, "meta", void 0);
3901
3839
  __decorate([(0, openapi_metadata_decorators.ApiProperty)({
@@ -3956,7 +3894,7 @@ __decorate([
3956
3894
  methods: ["get"],
3957
3895
  path: "/v1/config/rules",
3958
3896
  summary: "Get config rules",
3959
- description: "Returns configured rules for supported chains."
3897
+ description: "Returns configured rules (maturities, loan tokens, oracles) for supported chains."
3960
3898
  }),
3961
3899
  (0, openapi_metadata_decorators.ApiQuery)({
3962
3900
  name: "cursor",
@@ -4135,8 +4073,7 @@ const OpenApi = async () => {
4135
4073
  ObligationsController,
4136
4074
  HealthController,
4137
4075
  UsersController,
4138
- ValidateController,
4139
- CallbacksController
4076
+ ValidateController
4140
4077
  ],
4141
4078
  document: {
4142
4079
  openapi: "3.1.0",
@@ -4393,16 +4330,6 @@ const GetBookParams = zod.object({
4393
4330
  })
4394
4331
  });
4395
4332
  const ValidateOffersBody = zod.object({ offers: zod.array(zod.unknown()).min(1, { message: "'offers' must contain at least 1 offer" }) }).strict();
4396
- const CallbackTypesBody = zod.object({ callbacks: zod.array(zod.object({
4397
- chain_id: zod.number().int().positive().meta({
4398
- description: "Chain id.",
4399
- example: 1
4400
- }),
4401
- addresses: zod.array(zod.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "Callback address must be a valid 20-byte address" }).transform((val) => val.toLowerCase())).meta({
4402
- description: "Callback contract addresses.",
4403
- example: ["0x1111111111111111111111111111111111111111", "0x3333333333333333333333333333333333333333"]
4404
- })
4405
- }).strict()) }).strict();
4406
4333
  const GetUserPositionsParams = zod.object({
4407
4334
  ...PaginationQueryParams.shape,
4408
4335
  user_address: zod.string().regex(/^0x[a-fA-F0-9]{40}$/, { error: "User address must be a valid 20-byte address" }).transform((val) => val.toLowerCase()).meta({
@@ -4421,7 +4348,6 @@ const schemas = {
4421
4348
  get_obligation: GetObligationParams,
4422
4349
  get_book: GetBookParams,
4423
4350
  validate_offers: ValidateOffersBody,
4424
- callback_types: CallbackTypesBody,
4425
4351
  get_user_positions: GetUserPositionsParams
4426
4352
  };
4427
4353
  function parse(action, query) {
@@ -4436,7 +4362,6 @@ function safeParse(action, query, error) {
4436
4362
  var Schema_exports = /* @__PURE__ */ __exportAll({
4437
4363
  BookResponse: () => BookResponse_exports,
4438
4364
  BooksController: () => BooksController,
4439
- CallbacksController: () => CallbacksController,
4440
4365
  ChainHealth: () => ChainHealth,
4441
4366
  ChainsHealthResponse: () => ChainsHealthResponse,
4442
4367
  CollectorHealth: () => CollectorHealth,
@@ -4715,23 +4640,11 @@ function createHttpClient(config) {
4715
4640
  issues: []
4716
4641
  };
4717
4642
  };
4718
- const getCallbackTypes = async (requestPayload) => {
4719
- const response = await request("/v1/callbacks", {
4720
- method: "POST",
4721
- headers: { "content-type": "application/json" },
4722
- body: JSON.stringify(requestPayload)
4723
- });
4724
- const json = await response.json();
4725
- if (!response.ok) throw new Error(`Gatekeeper callbacks request failed: ${extractErrorMessage(json) ?? response.statusText}`);
4726
- if (!("data" in json) || !Array.isArray(json.data)) throw new Error("Gatekeeper callbacks response is invalid.");
4727
- return json.data;
4728
- };
4729
4643
  return {
4730
4644
  baseUrl,
4731
4645
  validate,
4732
4646
  getConfigRules,
4733
- isAllowed,
4734
- getCallbackTypes
4647
+ isAllowed
4735
4648
  };
4736
4649
  }
4737
4650
  function mergeHeaders(base, extra) {
@@ -4855,36 +4768,6 @@ function create(parameters) {
4855
4768
 
4856
4769
  //#endregion
4857
4770
  //#region src/gatekeeper/GateConfig.ts
4858
- /**
4859
- * Returns the callback configuration for a given chain and callback type, if it exists.
4860
- *
4861
- * @param chain - Chain name for which to read the validation configuration
4862
- * @param type - Callback type to retrieve
4863
- * @returns The matching callback configuration or undefined if not configured
4864
- */
4865
- function getCallback(chain, type) {
4866
- return configs[chain].callbacks?.find((c) => c.type === type);
4867
- }
4868
- /**
4869
- * Attempts to infer the configured callback type from a callback address on a chain.
4870
- * Skips the empty callback type as it does not carry addresses.
4871
- *
4872
- * @param chain - Chain name for which to infer the callback type
4873
- * @param address - Callback contract address
4874
- * @returns The callback type when found, otherwise undefined
4875
- */
4876
- function getCallbackType(chain, address) {
4877
- return configs[chain].callbacks?.find((c) => c.type !== Type$1.BuyWithEmptyCallback && c.addresses.includes(address?.toLowerCase()))?.type;
4878
- }
4879
- /**
4880
- * Returns the list of allowed non-empty callback addresses for a chain.
4881
- *
4882
- * @param chain - Chain name
4883
- * @returns Array of allowed callback addresses (lowercased). Empty when none configured
4884
- */
4885
- const getCallbackAddresses = (chain) => {
4886
- return configs[chain].callbacks?.filter((c) => c.type !== Type$1.BuyWithEmptyCallback).flatMap((c) => c.addresses) ?? [];
4887
- };
4888
4771
  const assets = {
4889
4772
  [ChainId.ETHEREUM.toString()]: [
4890
4773
  "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
@@ -4956,63 +4839,19 @@ const oracles = {
4956
4839
  };
4957
4840
  const configs = {
4958
4841
  ethereum: {
4959
- callbacks: [
4960
- {
4961
- type: Type$1.BuyVaultV1Callback,
4962
- addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4963
- vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
4964
- },
4965
- {
4966
- type: Type$1.SellERC20Callback,
4967
- addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4968
- },
4969
- { type: Type$1.BuyWithEmptyCallback }
4970
- ],
4842
+ callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
4971
4843
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4972
4844
  },
4973
4845
  base: {
4974
- callbacks: [
4975
- {
4976
- type: Type$1.BuyVaultV1Callback,
4977
- addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4978
- vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0xFf62A7c278C62eD665133147129245053Bbf5918"]
4979
- },
4980
- {
4981
- type: Type$1.SellERC20Callback,
4982
- addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4983
- },
4984
- { type: Type$1.BuyWithEmptyCallback }
4985
- ],
4846
+ callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
4986
4847
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
4987
4848
  },
4988
4849
  "ethereum-virtual-testnet": {
4989
- callbacks: [
4990
- {
4991
- type: Type$1.BuyVaultV1Callback,
4992
- addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
4993
- vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
4994
- },
4995
- {
4996
- type: Type$1.SellERC20Callback,
4997
- addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
4998
- },
4999
- { type: Type$1.BuyWithEmptyCallback }
5000
- ],
4850
+ callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5001
4851
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
5002
4852
  },
5003
4853
  anvil: {
5004
- callbacks: [
5005
- {
5006
- type: Type$1.BuyVaultV1Callback,
5007
- addresses: ["0x3333333333333333333333333333333333333333", "0x4444444444444444444444444444444444444444"],
5008
- vaultFactories: ["0xA9c3D3a366466Fa809d1Ae982Fb2c46E5fC41101", "0x1897A8997241C1cD4bD0698647e4EB7213535c24"]
5009
- },
5010
- {
5011
- type: Type$1.SellERC20Callback,
5012
- addresses: ["0x1111111111111111111111111111111111111111", "0x2222222222222222222222222222222222222222"]
5013
- },
5014
- { type: Type$1.BuyWithEmptyCallback }
5015
- ],
4854
+ callbacks: [{ type: Type$1.BuyWithEmptyCallback }, { type: Type$1.SellWithEmptyCallback }],
5016
4855
  maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth]
5017
4856
  }
5018
4857
  };
@@ -5032,109 +4871,13 @@ var Rules_exports = /* @__PURE__ */ __exportAll({
5032
4871
  /**
5033
4872
  * set of rules to validate offers.
5034
4873
  *
5035
- * @param parameters - Validity parameters with chain and client
4874
+ * @param _parameters - Validity parameters with chain and client
5036
4875
  * @returns Array of validation rules to evaluate against offers
5037
4876
  */
5038
- function validity(parameters) {
5039
- const { client } = parameters;
5040
- const sellErc20CallbackInvalid = single("sell_erc20_callback_invalid", "Validates that sell offers have valid ERC20 callback data matching offer collaterals", (offer) => {
5041
- const callbackType = getCallbackType(client.chain.name, offer.callback.address);
5042
- if (callbackType !== Type$1.SellERC20Callback) return;
5043
- const decoded = decode$2(callbackType, offer.callback.data);
5044
- if (decoded.length === 0) return { message: "Callback data cannot be decoded or is empty." };
5045
- if (callbackType === Type$1.SellERC20Callback) {
5046
- const offerCollaterals = new Set(offer.collaterals.map((c) => c.asset.toLowerCase()));
5047
- if (decoded.length !== offer.collaterals.length) return { message: `Sell callback collateral length mismatch. Expected ${offer.collaterals.length}, got ${decoded.length}.` };
5048
- for (const { contract } of decoded) if (!offerCollaterals.has(contract.toLowerCase())) return { message: "Sell callback collateral is not part of offer collaterals." };
5049
- }
5050
- });
5051
- const buyCallbackVaultInvalid = batch("buy_offers_callback_vault_invalid", "Validates that buy offers have valid vault callbacks registered in allowed factories with matching assets", async (offers) => {
5052
- const validationIssues = /* @__PURE__ */ new Map();
5053
- const offersByVaultAddress = /* @__PURE__ */ new Map();
5054
- for (let i = 0; i < offers.length; i++) {
5055
- const offer = offers[i];
5056
- if (getCallbackType(client.chain.name, offer.callback.address) !== Type$1.BuyVaultV1Callback) continue;
5057
- try {
5058
- const callbackVaults = decodeBuyVaultV1Callback(offer.callback.data);
5059
- for (const { contract } of callbackVaults) {
5060
- const normalizedVaultAddress = contract.toLowerCase();
5061
- if (!offersByVaultAddress.has(normalizedVaultAddress)) offersByVaultAddress.set(normalizedVaultAddress, []);
5062
- offersByVaultAddress.get(normalizedVaultAddress).push({
5063
- index: i,
5064
- offer
5065
- });
5066
- }
5067
- } catch (_) {}
5068
- }
5069
- const uniqueVaultAddresses = Array.from(offersByVaultAddress.keys());
5070
- if (uniqueVaultAddresses.length === 0) return validationIssues;
5071
- const allowedFactories = getCallback(client.chain.name, Type$1.BuyVaultV1Callback)?.vaultFactories.map((f) => f.toLowerCase());
5072
- if (!allowedFactories) return validationIssues;
5073
- const multicallContracts = [];
5074
- for (const vaultAddress of uniqueVaultAddresses) {
5075
- multicallContracts.push({
5076
- address: vaultAddress,
5077
- abi: ERC4626,
5078
- functionName: "asset"
5079
- });
5080
- for (const factoryAddress of allowedFactories) multicallContracts.push({
5081
- address: factoryAddress,
5082
- abi: MetaMorphoFactory,
5083
- functionName: "isMetaMorpho",
5084
- args: [vaultAddress]
5085
- });
5086
- }
5087
- const multicallResults = await (0, viem_actions.multicall)(client, {
5088
- contracts: multicallContracts,
5089
- allowFailure: true
5090
- });
5091
- const vaultAssetByAddress = /* @__PURE__ */ new Map();
5092
- const registeredVaults = /* @__PURE__ */ new Set();
5093
- const numberOfFactories = allowedFactories.length;
5094
- let resultIndex = 0;
5095
- for (const vaultAddress of uniqueVaultAddresses) {
5096
- const assetCallResult = multicallResults[resultIndex++];
5097
- const assetAddress = assetCallResult.status === "success" ? assetCallResult.result : null;
5098
- vaultAssetByAddress.set(vaultAddress, assetAddress);
5099
- let isRegisteredInFactory = false;
5100
- for (let factoryIndex = 0; factoryIndex < numberOfFactories; factoryIndex++) {
5101
- const factoryCallResult = multicallResults[resultIndex++];
5102
- if (factoryCallResult.status === "success" && factoryCallResult.result === true) isRegisteredInFactory = true;
5103
- }
5104
- if (isRegisteredInFactory) registeredVaults.add(vaultAddress);
5105
- }
5106
- const uniqueOffers = /* @__PURE__ */ new Map();
5107
- for (const offersArray of offersByVaultAddress.values()) for (const { index, offer } of offersArray) uniqueOffers.set(index, offer);
5108
- for (const [index, offer] of uniqueOffers) try {
5109
- const callbackVaults = decodeBuyVaultV1Callback(offer.callback.data);
5110
- const vaultsWithIssues = [];
5111
- for (const { contract } of callbackVaults) {
5112
- const normalizedVaultAddress = contract.toLowerCase();
5113
- const assetAddress = vaultAssetByAddress.get(normalizedVaultAddress);
5114
- const isRegistered = registeredVaults.has(normalizedVaultAddress);
5115
- const failureReasons = [];
5116
- if (assetAddress === null) failureReasons.push("asset call failed");
5117
- else if (assetAddress && assetAddress.toLowerCase() !== offer.loanToken.toLowerCase()) failureReasons.push("asset mismatch");
5118
- if (!isRegistered) failureReasons.push("not registered in factory");
5119
- if (failureReasons.length > 0) vaultsWithIssues.push({
5120
- vaultAddress: contract,
5121
- failureReasons: failureReasons.join(", ")
5122
- });
5123
- }
5124
- if (vaultsWithIssues.length > 0) {
5125
- const failureDetails = vaultsWithIssues.map((v) => `${v.vaultAddress} (${v.failureReasons})`).join("; ");
5126
- validationIssues.set(index, { message: `Buy offer callback vaults are invalid: ${failureDetails}` });
5127
- }
5128
- } catch (_) {}
5129
- return validationIssues;
5130
- });
5131
- return [
5132
- single("expiry", "Validates that offer has not expired", (offer) => {
5133
- if (offer.expiry < Math.floor(Date.now() / 1e3)) return { message: "Expiry mismatch" };
5134
- }),
5135
- sellErc20CallbackInvalid,
5136
- buyCallbackVaultInvalid
5137
- ];
4877
+ function validity(_parameters) {
4878
+ return [single("expiry", "Validates that offer has not expired", (offer) => {
4879
+ if (offer.expiry < Math.floor(Date.now() / 1e3)) return { message: "Expiry mismatch" };
4880
+ })];
5138
4881
  }
5139
4882
  const chains = ({ chains }) => single("chain_ids", `Validates that offer chain is one of: [${chains.map((c) => c.id).join(", ")}]`, (offer) => {
5140
4883
  const allowedChainIds = chains.map((c) => c.id);
@@ -5144,12 +4887,10 @@ const maturity = ({ maturities }) => single("maturity", `Validates that offer ma
5144
4887
  const allowedMaturities = maturities.map((m) => from$11(m));
5145
4888
  if (!allowedMaturities.includes(offer.maturity)) return { message: `Maturity must be end of current month (${allowedMaturities[0]}) or end of next month (${allowedMaturities[1]}). Got: ${offer.maturity}` };
5146
4889
  });
5147
- const callback = ({ callbacks, allowedAddresses }) => single("callback", `Validates callbacks: buy empty callback is ${callbacks.includes(Type$1.BuyWithEmptyCallback) ? "allowed" : "not allowed"}; sell offers must use a non-empty callback; non-empty callbacks must target one of [${allowedAddresses.map((a) => a.toLowerCase()).join(", ")}]`, (offer) => {
5148
- if (isEmptyCallback(offer) && offer.buy && !callbacks?.find((c) => c === Type$1.BuyWithEmptyCallback)) return { message: "Buy offers with empty callback not allowed." };
5149
- if (isEmptyCallback(offer) && !offer.buy) return { message: "Sell offers require a non-empty callback." };
5150
- if (!isEmptyCallback(offer)) {
5151
- if (!allowedAddresses.includes(offer.callback.address?.toLowerCase())) return { message: `Callback address ${offer.callback.address} is not allowed.` };
5152
- }
4890
+ const callback = ({ callbacks }) => single("callback", `Validates callbacks: buy empty callback is ${callbacks.includes(Type$1.BuyWithEmptyCallback) ? "allowed" : "not allowed"}; sell empty callback is ${callbacks.includes(Type$1.SellWithEmptyCallback) ? "allowed" : "not allowed"}; non-empty callbacks are rejected`, (offer) => {
4891
+ if (!isEmptyCallback(offer)) return { message: "Non-empty callbacks are not supported." };
4892
+ if (isEmptyCallback(offer) && offer.buy && !callbacks.includes(Type$1.BuyWithEmptyCallback)) return { message: "Buy offers with empty callback not allowed." };
4893
+ if (isEmptyCallback(offer) && !offer.buy && !callbacks.includes(Type$1.SellWithEmptyCallback)) return { message: "Sell offers with empty callback not allowed." };
5153
4894
  });
5154
4895
  /**
5155
4896
  * A validation rule that checks if the offer's tokens are allowed for its chain.
@@ -5214,12 +4955,8 @@ const morphoRules = (chains$2) => {
5214
4955
  chains({ chains: chains$2 }),
5215
4956
  maturity({ maturities: [MaturityType.EndOfMonth, MaturityType.EndOfNextMonth] }),
5216
4957
  callback({
5217
- callbacks: [
5218
- Type$1.BuyWithEmptyCallback,
5219
- Type$1.BuyVaultV1Callback,
5220
- Type$1.SellERC20Callback
5221
- ],
5222
- allowedAddresses: chains$2.flatMap((c) => getCallbackAddresses(c.name))
4958
+ callbacks: [Type$1.BuyWithEmptyCallback, Type$1.SellWithEmptyCallback],
4959
+ allowedAddresses: []
5223
4960
  }),
5224
4961
  token({ assetsByChainId }),
5225
4962
  oracle({ oraclesByChainId })