@sherwoodagent/cli 0.88.1 → 0.89.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/dist/{abis-WJQ6IVYV.js → abis-2VBXBA7Y.js} +16 -2
  2. package/dist/{agent-FCGZL4GF.js → agent-KMLNSKBS.js} +11 -11
  3. package/dist/{chat-AKLYUJZV.js → chat-JW5Z3JRE.js} +13 -13
  4. package/dist/{chunk-6SAE2VDK.js → chunk-6IC2NRED.js} +2 -2
  5. package/dist/{chunk-HMFPP2PE.js → chunk-77MBGRE5.js} +52 -24
  6. package/dist/chunk-77MBGRE5.js.map +1 -0
  7. package/dist/{chunk-G5MXVAFC.js → chunk-D3GTHAJS.js} +5 -5
  8. package/dist/chunk-G5FOHSQW.js +338 -0
  9. package/dist/chunk-G5FOHSQW.js.map +1 -0
  10. package/dist/chunk-GAQMHH44.js +18 -0
  11. package/dist/chunk-GAQMHH44.js.map +1 -0
  12. package/dist/{chunk-FWQESFFM.js → chunk-GYGSKMZE.js} +91 -8
  13. package/dist/chunk-GYGSKMZE.js.map +1 -0
  14. package/dist/{chunk-J2IZWAEW.js → chunk-JCL2DEH3.js} +2048 -2
  15. package/dist/chunk-JCL2DEH3.js.map +1 -0
  16. package/dist/{chunk-BH3VTJ4F.js → chunk-JKSDCCVL.js} +6 -6
  17. package/dist/{chunk-EEI6FRTE.js → chunk-JLOROS5V.js} +3 -3
  18. package/dist/{chunk-6D3FNU75.js → chunk-JRGYI34A.js} +5 -5
  19. package/dist/chunk-KZGY7NT7.js +209 -0
  20. package/dist/chunk-KZGY7NT7.js.map +1 -0
  21. package/dist/{chunk-G3FUEM5N.js → chunk-LIW6K4OJ.js} +2 -2
  22. package/dist/{chunk-4ITTHKRX.js → chunk-P4LFNKSX.js} +5 -5
  23. package/dist/{chunk-3TZIOAPH.js → chunk-QUAVAJWE.js} +13 -2
  24. package/dist/chunk-QUAVAJWE.js.map +1 -0
  25. package/dist/chunk-QVXKYT2N.js +489 -0
  26. package/dist/chunk-QVXKYT2N.js.map +1 -0
  27. package/dist/chunk-UPRFO4YU.js +458 -0
  28. package/dist/chunk-UPRFO4YU.js.map +1 -0
  29. package/dist/{chunk-QFGZQYZA.js → chunk-WDPA2BYK.js} +1024 -87
  30. package/dist/chunk-WDPA2BYK.js.map +1 -0
  31. package/dist/{chunk-CWGP4VXZ.js → chunk-YIN6R66K.js} +7 -7
  32. package/dist/{chunk-D4BSBW3Q.js → chunk-Z53JZORT.js} +3 -3
  33. package/dist/{chunk-SCQAKMMI.js → chunk-ZPOPWFSP.js} +5 -5
  34. package/dist/{client-PYFE6YQR.js → client-DA434B67.js} +4 -4
  35. package/dist/{config-ZGFS4I7K.js → config-UZ2GIXAO.js} +6 -2
  36. package/dist/{eas-B4HR2HXX.js → eas-ZH7BDEOK.js} +7 -7
  37. package/dist/{governor-QFBN6RYS.js → governor-WHT2V2EU.js} +7 -7
  38. package/dist/identity-TRPUQEQK.js +19 -0
  39. package/dist/index.js +8848 -6933
  40. package/dist/index.js.map +1 -1
  41. package/dist/launchpad-3N4ZFL6J.js +26 -0
  42. package/dist/lighter-perp-template-VC4TB7AM.js +92 -0
  43. package/dist/lighter-preflight-GH3JKLR6.js +149 -0
  44. package/dist/lighter-preflight-GH3JKLR6.js.map +1 -0
  45. package/dist/{network-7445KSCF.js → network-EZ5X2BF7.js} +3 -3
  46. package/dist/network-EZ5X2BF7.js.map +1 -0
  47. package/dist/{price-EXZDYVDD.js → price-RX5J7GTO.js} +9 -7
  48. package/dist/{price-EXZDYVDD.js.map → price-RX5J7GTO.js.map} +1 -1
  49. package/dist/{providers-6UZKDFQD.js → providers-XEEFKITN.js} +5 -5
  50. package/dist/{research-T7A27OMB.js → research-PYMQ5VKH.js} +9 -9
  51. package/dist/{session-45NQAHFI.js → session-DE47TUEW.js} +15 -15
  52. package/dist/{trade-ZOVM433K.js → trade-3VMAQ75D.js} +20 -18
  53. package/dist/{trade-ZOVM433K.js.map → trade-3VMAQ75D.js.map} +1 -1
  54. package/dist/{vault-E7XD6DLD.js → vault-PXGG2E3K.js} +9 -9
  55. package/dist/vault-PXGG2E3K.js.map +1 -0
  56. package/dist/{xmtp-72IRK7JL.js → xmtp-5PTIIVAI.js} +7 -7
  57. package/package.json +1 -1
  58. package/dist/chunk-3TZIOAPH.js.map +0 -1
  59. package/dist/chunk-FWQESFFM.js.map +0 -1
  60. package/dist/chunk-HMFPP2PE.js.map +0 -1
  61. package/dist/chunk-J2IZWAEW.js.map +0 -1
  62. package/dist/chunk-QFGZQYZA.js.map +0 -1
  63. package/dist/identity-I2BG4IGT.js +0 -18
  64. /package/dist/{abis-WJQ6IVYV.js.map → abis-2VBXBA7Y.js.map} +0 -0
  65. /package/dist/{agent-FCGZL4GF.js.map → agent-KMLNSKBS.js.map} +0 -0
  66. /package/dist/{chat-AKLYUJZV.js.map → chat-JW5Z3JRE.js.map} +0 -0
  67. /package/dist/{chunk-6SAE2VDK.js.map → chunk-6IC2NRED.js.map} +0 -0
  68. /package/dist/{chunk-G5MXVAFC.js.map → chunk-D3GTHAJS.js.map} +0 -0
  69. /package/dist/{chunk-BH3VTJ4F.js.map → chunk-JKSDCCVL.js.map} +0 -0
  70. /package/dist/{chunk-EEI6FRTE.js.map → chunk-JLOROS5V.js.map} +0 -0
  71. /package/dist/{chunk-6D3FNU75.js.map → chunk-JRGYI34A.js.map} +0 -0
  72. /package/dist/{chunk-G3FUEM5N.js.map → chunk-LIW6K4OJ.js.map} +0 -0
  73. /package/dist/{chunk-4ITTHKRX.js.map → chunk-P4LFNKSX.js.map} +0 -0
  74. /package/dist/{chunk-CWGP4VXZ.js.map → chunk-YIN6R66K.js.map} +0 -0
  75. /package/dist/{chunk-D4BSBW3Q.js.map → chunk-Z53JZORT.js.map} +0 -0
  76. /package/dist/{chunk-SCQAKMMI.js.map → chunk-ZPOPWFSP.js.map} +0 -0
  77. /package/dist/{client-PYFE6YQR.js.map → client-DA434B67.js.map} +0 -0
  78. /package/dist/{config-ZGFS4I7K.js.map → config-UZ2GIXAO.js.map} +0 -0
  79. /package/dist/{eas-B4HR2HXX.js.map → eas-ZH7BDEOK.js.map} +0 -0
  80. /package/dist/{governor-QFBN6RYS.js.map → governor-WHT2V2EU.js.map} +0 -0
  81. /package/dist/{identity-I2BG4IGT.js.map → identity-TRPUQEQK.js.map} +0 -0
  82. /package/dist/{network-7445KSCF.js.map → launchpad-3N4ZFL6J.js.map} +0 -0
  83. /package/dist/{vault-E7XD6DLD.js.map → lighter-perp-template-VC4TB7AM.js.map} +0 -0
  84. /package/dist/{providers-6UZKDFQD.js.map → providers-XEEFKITN.js.map} +0 -0
  85. /package/dist/{research-T7A27OMB.js.map → research-PYMQ5VKH.js.map} +0 -0
  86. /package/dist/{session-45NQAHFI.js.map → session-DE47TUEW.js.map} +0 -0
  87. /package/dist/{xmtp-72IRK7JL.js.map → xmtp-5PTIIVAI.js.map} +0 -0
@@ -1,33 +1,49 @@
1
+ import {
2
+ LIGHTER_USDG,
3
+ buildExecuteCalls,
4
+ buildInitData,
5
+ buildSettleCalls,
6
+ parseLighterTemplateFlags,
7
+ usdgToTicks
8
+ } from "./chunk-G5FOHSQW.js";
9
+ import {
10
+ buildExecuteCalls as buildExecuteCalls2,
11
+ buildInitData as buildInitData2,
12
+ buildLaunchpadInitParams,
13
+ buildSettleCalls as buildSettleCalls2
14
+ } from "./chunk-QVXKYT2N.js";
1
15
  import {
2
16
  AERODROME,
3
17
  CHAINLINK,
4
18
  MOONWELL,
5
19
  ROBINHOOD_STOCK_ROUTES,
20
+ STRATEGY_VENUES,
6
21
  SYNTHRA,
7
22
  TOKENS,
8
23
  UNISWAP,
9
24
  VENICE
10
- } from "./chunk-FWQESFFM.js";
25
+ } from "./chunk-GYGSKMZE.js";
11
26
  import {
12
27
  getPublicClient
13
- } from "./chunk-D4BSBW3Q.js";
28
+ } from "./chunk-Z53JZORT.js";
14
29
  import {
15
30
  getNetwork
16
- } from "./chunk-G3FUEM5N.js";
31
+ } from "./chunk-LIW6K4OJ.js";
17
32
  import {
18
33
  BASE_STRATEGY_ABI,
34
+ CONCENTRATED_LIQUIDITY_STRATEGY_ABI,
19
35
  ERC20_ABI,
20
36
  UNISWAP_QUOTER_V2_ABI
21
- } from "./chunk-J2IZWAEW.js";
37
+ } from "./chunk-JCL2DEH3.js";
22
38
 
23
39
  // src/lib/swap-router.ts
24
- import { encodeFunctionData as encodeFunctionData9, decodeFunctionResult } from "viem";
40
+ import { encodeFunctionData as encodeFunctionData11, decodeFunctionResult } from "viem";
25
41
 
26
42
  // src/lib/template-encoder.ts
27
43
  import {
28
- parseUnits,
29
- isAddress,
30
- encodeAbiParameters as encodeAbiParameters9,
44
+ parseUnits as parseUnits2,
45
+ isAddress as isAddress2,
46
+ encodeAbiParameters as encodeAbiParameters12,
31
47
  concat as concat2,
32
48
  numberToHex
33
49
  } from "viem";
@@ -35,7 +51,7 @@ import chalk from "chalk";
35
51
 
36
52
  // src/strategies/moonwell-supply-template.ts
37
53
  import { encodeAbiParameters, encodeFunctionData } from "viem";
38
- function buildInitData(underlying, mToken, supplyAmount, minRedeemAmount, isNativeEthMarket) {
54
+ function buildInitData3(underlying, mToken, supplyAmount, minRedeemAmount, isNativeEthMarket) {
39
55
  return encodeAbiParameters(
40
56
  [
41
57
  { type: "address" },
@@ -47,7 +63,7 @@ function buildInitData(underlying, mToken, supplyAmount, minRedeemAmount, isNati
47
63
  [underlying, mToken, supplyAmount, minRedeemAmount, isNativeEthMarket]
48
64
  );
49
65
  }
50
- function buildExecuteCalls(clone, underlying, supplyAmount) {
66
+ function buildExecuteCalls3(clone, underlying, supplyAmount) {
51
67
  return [
52
68
  {
53
69
  target: underlying,
@@ -68,7 +84,7 @@ function buildExecuteCalls(clone, underlying, supplyAmount) {
68
84
  }
69
85
  ];
70
86
  }
71
- function buildSettleCalls(clone) {
87
+ function buildSettleCalls3(clone) {
72
88
  return [
73
89
  {
74
90
  target: clone,
@@ -101,10 +117,10 @@ var INIT_PARAMS_TYPES = [
101
117
  ]
102
118
  }
103
119
  ];
104
- function buildInitData2(params) {
120
+ function buildInitData4(params) {
105
121
  return encodeAbiParameters2(INIT_PARAMS_TYPES, [params]);
106
122
  }
107
- function buildExecuteCalls2(clone, asset, assetAmount) {
123
+ function buildExecuteCalls4(clone, asset, assetAmount) {
108
124
  return [
109
125
  {
110
126
  target: asset,
@@ -125,7 +141,7 @@ function buildExecuteCalls2(clone, asset, assetAmount) {
125
141
  }
126
142
  ];
127
143
  }
128
- function buildSettleCalls2(clone) {
144
+ function buildSettleCalls4(clone) {
129
145
  return [
130
146
  {
131
147
  target: clone,
@@ -160,10 +176,10 @@ var INIT_PARAMS_TYPES2 = [
160
176
  ]
161
177
  }
162
178
  ];
163
- function buildInitData3(params) {
179
+ function buildInitData5(params) {
164
180
  return encodeAbiParameters3(INIT_PARAMS_TYPES2, [params]);
165
181
  }
166
- function buildExecuteCalls3(clone, tokenA, amountA, tokenB, amountB) {
182
+ function buildExecuteCalls5(clone, tokenA, amountA, tokenB, amountB) {
167
183
  return [
168
184
  {
169
185
  target: tokenA,
@@ -193,7 +209,7 @@ function buildExecuteCalls3(clone, tokenA, amountA, tokenB, amountB) {
193
209
  }
194
210
  ];
195
211
  }
196
- function buildSettleCalls3(clone) {
212
+ function buildSettleCalls5(clone) {
197
213
  return [
198
214
  {
199
215
  target: clone,
@@ -225,10 +241,10 @@ var INIT_PARAMS_TYPES3 = [
225
241
  ]
226
242
  }
227
243
  ];
228
- function buildInitData4(params) {
244
+ function buildInitData6(params) {
229
245
  return encodeAbiParameters4(INIT_PARAMS_TYPES3, [params]);
230
246
  }
231
- function buildExecuteCalls4(clone, weth, supplyAmount) {
247
+ function buildExecuteCalls6(clone, weth, supplyAmount) {
232
248
  const approveAmount = supplyAmount === 0n ? maxUint256 : supplyAmount;
233
249
  return [
234
250
  {
@@ -259,7 +275,7 @@ function buildExecuteCalls4(clone, weth, supplyAmount) {
259
275
  }
260
276
  ];
261
277
  }
262
- function buildSettleCalls4(clone) {
278
+ function buildSettleCalls6(clone) {
263
279
  return [
264
280
  {
265
281
  target: clone,
@@ -274,7 +290,7 @@ function buildSettleCalls4(clone) {
274
290
 
275
291
  // src/strategies/mamo-yield-template.ts
276
292
  import { encodeAbiParameters as encodeAbiParameters5, encodeFunctionData as encodeFunctionData5 } from "viem";
277
- function buildInitData5(underlying, mamoFactory, minRedeemAmount) {
293
+ function buildInitData7(underlying, mamoFactory, minRedeemAmount) {
278
294
  return encodeAbiParameters5(
279
295
  [
280
296
  { type: "address" },
@@ -284,7 +300,7 @@ function buildInitData5(underlying, mamoFactory, minRedeemAmount) {
284
300
  [underlying, mamoFactory, minRedeemAmount]
285
301
  );
286
302
  }
287
- function buildExecuteCalls5(clone, underlying, amount) {
303
+ function buildExecuteCalls7(clone, underlying, amount) {
288
304
  return [
289
305
  {
290
306
  target: underlying,
@@ -305,7 +321,7 @@ function buildExecuteCalls5(clone, underlying, amount) {
305
321
  }
306
322
  ];
307
323
  }
308
- function buildSettleCalls5(clone) {
324
+ function buildSettleCalls7(clone) {
309
325
  return [
310
326
  {
311
327
  target: clone,
@@ -355,7 +371,7 @@ function v4PathExtraData(hops) {
355
371
  )
356
372
  );
357
373
  }
358
- function buildInitData6(asset, swapAdapter, allocations, totalAmount, maxSlippageBps) {
374
+ function buildInitData8(asset, swapAdapter, allocations, totalAmount, maxSlippageBps) {
359
375
  const tokens = allocations.map((a) => a.token);
360
376
  const weightsBps = allocations.map((a) => BigInt(a.weightBps));
361
377
  const swapExtraData = allocations.map((a) => a.swapExtraData);
@@ -386,7 +402,7 @@ function buildInitData6(asset, swapAdapter, allocations, totalAmount, maxSlippag
386
402
  ]
387
403
  );
388
404
  }
389
- function buildExecuteCalls6(clone, asset, totalAmount) {
405
+ function buildExecuteCalls8(clone, asset, totalAmount) {
390
406
  return [
391
407
  {
392
408
  target: asset,
@@ -407,7 +423,7 @@ function buildExecuteCalls6(clone, asset, totalAmount) {
407
423
  }
408
424
  ];
409
425
  }
410
- function buildSettleCalls6(clone) {
426
+ function buildSettleCalls8(clone) {
411
427
  return [
412
428
  {
413
429
  target: clone,
@@ -801,7 +817,7 @@ var HYPERLIQUID_PERP_STRATEGY_ABI = [
801
817
  ];
802
818
 
803
819
  // src/strategies/hyperliquid-perp-template.ts
804
- function buildInitData7(asset, depositAmount, perpAssetIndex, leverage, maxPositionSize, maxTradesPerDay) {
820
+ function buildInitData9(asset, depositAmount, perpAssetIndex, leverage, maxPositionSize, maxTradesPerDay) {
805
821
  return encodeAbiParameters7(
806
822
  [
807
823
  { type: "address" },
@@ -814,7 +830,7 @@ function buildInitData7(asset, depositAmount, perpAssetIndex, leverage, maxPosit
814
830
  [asset, depositAmount, perpAssetIndex, leverage, maxPositionSize, maxTradesPerDay]
815
831
  );
816
832
  }
817
- function buildExecuteCalls7(clone, asset, amount) {
833
+ function buildExecuteCalls9(clone, asset, amount) {
818
834
  const approveAmount = amount === 0n ? maxUint2562 : amount;
819
835
  return [
820
836
  {
@@ -845,7 +861,7 @@ function buildExecuteCalls7(clone, asset, amount) {
845
861
  }
846
862
  ];
847
863
  }
848
- function buildSettleCalls7(clone) {
864
+ function buildSettleCalls9(clone) {
849
865
  return [
850
866
  {
851
867
  target: clone,
@@ -860,7 +876,7 @@ function buildSettleCalls7(clone) {
860
876
 
861
877
  // src/strategies/hyperliquid-grid-template.ts
862
878
  import { encodeAbiParameters as encodeAbiParameters8, encodeFunctionData as encodeFunctionData8, maxUint256 as maxUint2563 } from "viem";
863
- function buildInitData8(asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices) {
879
+ function buildInitData10(asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices) {
864
880
  return encodeAbiParameters8(
865
881
  [
866
882
  { type: "address" },
@@ -873,7 +889,7 @@ function buildInitData8(asset, depositAmount, leverage, maxOrderSize, maxOrdersP
873
889
  [asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices]
874
890
  );
875
891
  }
876
- function buildExecuteCalls8(clone, asset, amount) {
892
+ function buildExecuteCalls10(clone, asset, amount) {
877
893
  const approveAmount = amount === 0n ? maxUint2563 : amount;
878
894
  return [
879
895
  {
@@ -904,7 +920,7 @@ function buildExecuteCalls8(clone, asset, amount) {
904
920
  }
905
921
  ];
906
922
  }
907
- function buildSettleCalls8(clone) {
923
+ function buildSettleCalls10(clone) {
908
924
  return [
909
925
  {
910
926
  target: clone,
@@ -917,6 +933,827 @@ function buildSettleCalls8(clone) {
917
933
  ];
918
934
  }
919
935
 
936
+ // src/strategies/morpho-supply-template.ts
937
+ import { encodeAbiParameters as encodeAbiParameters10, encodeFunctionData as encodeFunctionData9, formatUnits, parseUnits } from "viem";
938
+
939
+ // src/strategies/morpho-cl-shared.ts
940
+ import { encodeAbiParameters as encodeAbiParameters9, isAddress, keccak256, toFunctionSelector } from "viem";
941
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
942
+ function viewOutputComponents(abi, fn) {
943
+ const entry = abi.find(
944
+ (e) => e.type === "function" && e.name === fn
945
+ );
946
+ const components = entry?.outputs?.[0]?.components;
947
+ if (!components) throw new Error(`generated ABI has no tuple output for ${fn}()`);
948
+ return components;
949
+ }
950
+ var MARKET_PARAMS_COMPONENTS = viewOutputComponents(
951
+ CONCENTRATED_LIQUIDITY_STRATEGY_ABI,
952
+ "marketParams"
953
+ );
954
+ function marketIdOf(mp) {
955
+ return keccak256(
956
+ encodeAbiParameters9(
957
+ [{ type: "address" }, { type: "address" }, { type: "address" }, { type: "address" }, { type: "uint256" }],
958
+ [mp.loanToken, mp.collateralToken, mp.oracle, mp.irm, mp.lltv]
959
+ )
960
+ );
961
+ }
962
+ function MORPHO_CL_VENUES() {
963
+ const v = STRATEGY_VENUES();
964
+ return {
965
+ MORPHO_BLUE: v.MORPHO_BLUE,
966
+ UNISWAP_V3_FACTORY: v.UNISWAP_V3_FACTORY,
967
+ UNISWAP_V3_POSITION_MANAGER: v.UNISWAP_V3_POSITION_MANAGER
968
+ };
969
+ }
970
+ var MORPHO_READ_ABI = [
971
+ {
972
+ type: "function",
973
+ name: "idToMarketParams",
974
+ stateMutability: "view",
975
+ inputs: [{ name: "id", type: "bytes32" }],
976
+ outputs: [{ name: "", type: "tuple", components: MARKET_PARAMS_COMPONENTS }]
977
+ },
978
+ {
979
+ type: "function",
980
+ name: "market",
981
+ stateMutability: "view",
982
+ inputs: [{ name: "id", type: "bytes32" }],
983
+ outputs: [
984
+ {
985
+ name: "",
986
+ type: "tuple",
987
+ components: [
988
+ { name: "totalSupplyAssets", type: "uint128" },
989
+ { name: "totalSupplyShares", type: "uint128" },
990
+ { name: "totalBorrowAssets", type: "uint128" },
991
+ { name: "totalBorrowShares", type: "uint128" },
992
+ { name: "lastUpdate", type: "uint128" },
993
+ { name: "fee", type: "uint128" }
994
+ ]
995
+ }
996
+ ]
997
+ }
998
+ ];
999
+ var TIER_BINDING_ABI = [
1000
+ { type: "function", name: "governor", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "address" }] },
1001
+ { type: "function", name: "tierRegistry", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "address" }] },
1002
+ {
1003
+ type: "function",
1004
+ name: "isCounterpartyAllowed",
1005
+ stateMutability: "view",
1006
+ inputs: [{ name: "counterparty", type: "address" }],
1007
+ outputs: [{ name: "", type: "bool" }]
1008
+ }
1009
+ ];
1010
+ var VAULT_ASSET_ABI = [
1011
+ { type: "function", name: "asset", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "address" }] }
1012
+ ];
1013
+ var ERC4626_PREVIEW_ABI = [
1014
+ { type: "function", name: "asset", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "address" }] },
1015
+ {
1016
+ type: "function",
1017
+ name: "previewDeposit",
1018
+ stateMutability: "view",
1019
+ inputs: [{ name: "assets", type: "uint256" }],
1020
+ outputs: [{ name: "", type: "uint256" }]
1021
+ },
1022
+ {
1023
+ type: "function",
1024
+ name: "previewRedeem",
1025
+ stateMutability: "view",
1026
+ inputs: [{ name: "shares", type: "uint256" }],
1027
+ outputs: [{ name: "", type: "uint256" }]
1028
+ }
1029
+ ];
1030
+ async function readTierRegistry(client, vault) {
1031
+ try {
1032
+ const governor = await client.readContract({
1033
+ address: vault,
1034
+ abi: TIER_BINDING_ABI,
1035
+ functionName: "governor"
1036
+ });
1037
+ if (!governor || governor === ZERO_ADDRESS) return null;
1038
+ const registry = await client.readContract({
1039
+ address: governor,
1040
+ abi: TIER_BINDING_ABI,
1041
+ functionName: "tierRegistry"
1042
+ });
1043
+ return registry && registry !== ZERO_ADDRESS ? registry : null;
1044
+ } catch {
1045
+ return null;
1046
+ }
1047
+ }
1048
+ async function readAllowed(client, registry, counterparties) {
1049
+ const out = {};
1050
+ const unique = [...new Set(counterparties.map((c) => c.toLowerCase()))];
1051
+ await Promise.all(
1052
+ unique.map(async (c) => {
1053
+ if (!registry) {
1054
+ out[c] = false;
1055
+ return;
1056
+ }
1057
+ try {
1058
+ out[c] = await client.readContract({
1059
+ address: registry,
1060
+ abi: TIER_BINDING_ABI,
1061
+ functionName: "isCounterpartyAllowed",
1062
+ args: [c]
1063
+ });
1064
+ } catch {
1065
+ out[c] = false;
1066
+ }
1067
+ })
1068
+ );
1069
+ return out;
1070
+ }
1071
+ function isAllowed(allowed, a) {
1072
+ return allowed[a.toLowerCase()] === true;
1073
+ }
1074
+ function sameAddress(a, b) {
1075
+ return a.toLowerCase() === b.toLowerCase();
1076
+ }
1077
+ function withSelector(signature) {
1078
+ return `${signature} [${toFunctionSelector(signature)}]`;
1079
+ }
1080
+ function parseAddressFlag(raw, flag) {
1081
+ const s = String(raw ?? "").trim();
1082
+ if (!isAddress(s)) throw new Error(`${flag} must be a 0x-address (got '${s}')`);
1083
+ return s;
1084
+ }
1085
+ function parseBytes32Flag(raw, flag) {
1086
+ const s = String(raw ?? "").trim();
1087
+ if (!/^0x[0-9a-fA-F]{64}$/.test(s)) throw new Error(`${flag} must be a 0x-prefixed 32-byte hex id (got '${s}')`);
1088
+ return s.toLowerCase();
1089
+ }
1090
+ function parseIntFlag(raw, flag, fallback, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER) {
1091
+ if (raw === void 0 || raw === null || raw === "") return fallback;
1092
+ const s = String(raw).trim();
1093
+ if (!/^-?\d+$/.test(s)) throw new Error(`${flag} must be an integer (got '${s}')`);
1094
+ const n = Number(s);
1095
+ if (n < min || n > max) throw new Error(`${flag} must be within [${min}, ${max}] (got ${n})`);
1096
+ return n;
1097
+ }
1098
+ function parseUintFlag(raw, flag, fallback) {
1099
+ if (raw === void 0 || raw === null || raw === "") return fallback;
1100
+ const s = String(raw).trim();
1101
+ if (!/^\d+$/.test(s)) throw new Error(`${flag} must be a non-negative integer (got '${s}')`);
1102
+ return BigInt(s);
1103
+ }
1104
+
1105
+ // src/strategies/morpho-supply-template.ts
1106
+ function buildInitData11(morpho, marketParams, supplyAmount) {
1107
+ return encodeAbiParameters10(
1108
+ [
1109
+ { type: "address" },
1110
+ { type: "tuple", components: MARKET_PARAMS_COMPONENTS },
1111
+ { type: "uint256" }
1112
+ ],
1113
+ [morpho, marketParams, supplyAmount]
1114
+ );
1115
+ }
1116
+ function buildExecuteCalls11(clone, asset, supplyAmount) {
1117
+ return [
1118
+ {
1119
+ target: asset,
1120
+ data: encodeFunctionData9({ abi: ERC20_ABI, functionName: "approve", args: [clone, supplyAmount] }),
1121
+ value: 0n
1122
+ },
1123
+ {
1124
+ target: clone,
1125
+ data: encodeFunctionData9({ abi: BASE_STRATEGY_ABI, functionName: "execute" }),
1126
+ value: 0n
1127
+ }
1128
+ ];
1129
+ }
1130
+ function buildSettleCalls11(clone) {
1131
+ return [
1132
+ {
1133
+ target: clone,
1134
+ data: encodeFunctionData9({ abi: BASE_STRATEGY_ABI, functionName: "settle" }),
1135
+ value: 0n
1136
+ }
1137
+ ];
1138
+ }
1139
+ function planMorphoSupply(inputs, state) {
1140
+ const errors = [];
1141
+ const warnings = [];
1142
+ const { morpho, marketId } = inputs;
1143
+ const mp = state.marketParams;
1144
+ if (sameAddress(morpho, ZERO_ADDRESS)) {
1145
+ errors.push(`${withSelector("ZeroAddress()")}: no Morpho Blue address \u2014 pass --morpho on this network`);
1146
+ }
1147
+ if (!state.tierRegistry) {
1148
+ errors.push(
1149
+ `${withSelector("TierRegistryUnresolved()")}: the vault's governor names no TierRegistry, so the strategy cannot bind Morpho`
1150
+ );
1151
+ } else if (!state.morphoAllowed) {
1152
+ errors.push(
1153
+ `${withSelector("MorphoNotAllowed(address,address)")}: Morpho ${morpho} is not counterparty-allowlisted on the vault's TierRegistry ${state.tierRegistry}`
1154
+ );
1155
+ }
1156
+ let supplyAmount = 0n;
1157
+ try {
1158
+ supplyAmount = parseUnits(inputs.amount, state.assetDecimals);
1159
+ } catch {
1160
+ errors.push(`--amount '${inputs.amount}' is not a decimal amount of ${state.assetSymbol}`);
1161
+ }
1162
+ if (supplyAmount === 0n) errors.push(`${withSelector("InvalidAmount()")}: --amount must be > 0`);
1163
+ const unknownMarket = sameAddress(mp.loanToken, ZERO_ADDRESS) && mp.lltv === 0n;
1164
+ if (unknownMarket) {
1165
+ errors.push(
1166
+ `${withSelector("MarketNotCreated()")}: market ${marketId} does not exist on Morpho ${morpho} (idToMarketParams is empty)`
1167
+ );
1168
+ } else {
1169
+ if (!sameAddress(mp.loanToken, state.vaultAsset)) {
1170
+ errors.push(
1171
+ `${withSelector("LoanAssetMismatch()")}: market ${marketId} lends ${mp.loanToken}, but the vault asset is ${state.vaultAsset} (${state.assetSymbol})`
1172
+ );
1173
+ }
1174
+ const derived = marketIdOf(mp);
1175
+ if (derived.toLowerCase() !== marketId.toLowerCase()) {
1176
+ errors.push(`market params returned for ${marketId} hash to ${derived} \u2014 not the market you named`);
1177
+ }
1178
+ if (state.market.lastUpdate === 0n) {
1179
+ errors.push(`${withSelector("MarketNotCreated()")}: market ${marketId} has never been created on ${morpho}`);
1180
+ }
1181
+ }
1182
+ if (supplyAmount > 0n && state.vaultBalance < supplyAmount) {
1183
+ errors.push(
1184
+ `vault holds ${formatUnits(state.vaultBalance, state.assetDecimals)} ${state.assetSymbol} but execute pulls ${formatUnits(supplyAmount, state.assetDecimals)} (--amount is in human units)`
1185
+ );
1186
+ }
1187
+ if (errors.length > 0) return { plan: null, errors, warnings };
1188
+ return {
1189
+ plan: { morpho, marketId, marketParams: mp, asset: state.vaultAsset, supplyAmount },
1190
+ errors,
1191
+ warnings
1192
+ };
1193
+ }
1194
+
1195
+ // src/strategies/concentrated-liquidity-template.ts
1196
+ import { encodeAbiParameters as encodeAbiParameters11, encodeFunctionData as encodeFunctionData10, formatUnits as formatUnits2 } from "viem";
1197
+ var BPS = 10000n;
1198
+ var FEE_DENOMINATOR = 1000000n;
1199
+ var MIN_TICK = -887272;
1200
+ var MAX_TICK = 887272;
1201
+ var MAX_POOL_SHARE_BPS = 1000n;
1202
+ var MIN_LLTV_BUFFER_BPS = 500n;
1203
+ var MAX_SLIPPAGE_BPS = 1e3;
1204
+ var MAX_TWAP_DEVIATION_BPS = 1e3;
1205
+ var MIN_TWAP_WINDOW = 300;
1206
+ var MAX_RERANGE_LIMIT = 20;
1207
+ var MAX_HALF_WIDTH_TICKS = MAX_TICK;
1208
+ var CL_DEFAULTS = {
1209
+ twapWindow: 1800,
1210
+ maxTwapDeviationBps: 100,
1211
+ mintSlippageBps: 500,
1212
+ settleSlippageBps: 500,
1213
+ settleDeadline: 0n,
1214
+ rerangeTriggerBps: 8e3,
1215
+ rerangeMinInterval: 3600n,
1216
+ maxReranges: 3,
1217
+ rerangeSlippageBps: 500
1218
+ };
1219
+ function rerangeComponents() {
1220
+ const entry = CONCENTRATED_LIQUIDITY_STRATEGY_ABI.find(
1221
+ (e) => e.type === "function" && e.name === "rerangePolicy"
1222
+ );
1223
+ const c = entry?.outputs?.[0]?.components;
1224
+ if (!c) throw new Error("generated ABI has no tuple output for rerangePolicy()");
1225
+ return c;
1226
+ }
1227
+ var INIT_PARAMS_COMPONENTS = [
1228
+ { name: "pool", type: "address" },
1229
+ { name: "positionManager", type: "address" },
1230
+ { name: "uniswapFactory", type: "address" },
1231
+ { name: "swapAdapter", type: "address" },
1232
+ { name: "morpho", type: "address" },
1233
+ { name: "marketParams", type: "tuple", components: MARKET_PARAMS_COMPONENTS },
1234
+ { name: "collateralAmount", type: "uint256" },
1235
+ { name: "borrowAmount", type: "uint256" },
1236
+ { name: "tickLower", type: "int24" },
1237
+ { name: "tickUpper", type: "int24" },
1238
+ { name: "expectedLiquidity", type: "uint128" },
1239
+ { name: "swapFractionBps", type: "uint256" },
1240
+ { name: "twapWindow", type: "uint32" },
1241
+ { name: "maxTwapDeviationBps", type: "uint256" },
1242
+ { name: "mintSlippageBps", type: "uint256" },
1243
+ { name: "rerange", type: "tuple", components: rerangeComponents() },
1244
+ { name: "settleSlippageBps", type: "uint256" },
1245
+ { name: "settleDeadline", type: "uint256" },
1246
+ { name: "swapExtraData", type: "bytes" }
1247
+ ];
1248
+ function buildInitData12(p) {
1249
+ return encodeAbiParameters11([{ type: "tuple", components: INIT_PARAMS_COMPONENTS }], [p]);
1250
+ }
1251
+ function buildExecuteCalls12(clone, asset, collateralAmount) {
1252
+ return [
1253
+ {
1254
+ target: asset,
1255
+ data: encodeFunctionData10({ abi: ERC20_ABI, functionName: "approve", args: [clone, collateralAmount] }),
1256
+ value: 0n
1257
+ },
1258
+ {
1259
+ target: clone,
1260
+ data: encodeFunctionData10({ abi: BASE_STRATEGY_ABI, functionName: "execute" }),
1261
+ value: 0n
1262
+ }
1263
+ ];
1264
+ }
1265
+ function buildSettleCalls12(clone) {
1266
+ return [
1267
+ {
1268
+ target: clone,
1269
+ data: encodeFunctionData10({ abi: BASE_STRATEGY_ABI, functionName: "settle" }),
1270
+ value: 0n
1271
+ }
1272
+ ];
1273
+ }
1274
+ var Q96 = 1n << 96n;
1275
+ var MAX_UINT256 = (1n << 256n) - 1n;
1276
+ function getSqrtRatioAtTick(tick) {
1277
+ if (!Number.isInteger(tick)) throw new Error(`tick must be an integer (got ${tick})`);
1278
+ const absTick = BigInt(Math.abs(tick));
1279
+ if (absTick > BigInt(MAX_TICK)) throw new Error(`tick ${tick} outside [${MIN_TICK}, ${MAX_TICK}]`);
1280
+ let ratio = (absTick & 0x1n) !== 0n ? 0xfffcb933bd6fad37aa2d162d1a594001n : 0x100000000000000000000000000000000n;
1281
+ const steps = [
1282
+ [0x2n, 0xfff97272373d413259a46990580e213an],
1283
+ [0x4n, 0xfff2e50f5f656932ef12357cf3c7fdccn],
1284
+ [0x8n, 0xffe5caca7e10e4e61c3624eaa0941cd0n],
1285
+ [0x10n, 0xffcb9843d60f6159c9db58835c926644n],
1286
+ [0x20n, 0xff973b41fa98c081472e6896dfb254c0n],
1287
+ [0x40n, 0xff2ea16466c96a3843ec78b326b52861n],
1288
+ [0x80n, 0xfe5dee046a99a2a811c461f1969c3053n],
1289
+ [0x100n, 0xfcbe86c7900a88aedcffc83b479aa3a4n],
1290
+ [0x200n, 0xf987a7253ac413176f2b074cf7815e54n],
1291
+ [0x400n, 0xf3392b0822b70005940c7a398e4b70f3n],
1292
+ [0x800n, 0xe7159475a2c29b7443b29c7fa6e889d9n],
1293
+ [0x1000n, 0xd097f3bdfd2022b8845ad8f792aa5825n],
1294
+ [0x2000n, 0xa9f746462d870fdf8a65dc1f90e061e5n],
1295
+ [0x4000n, 0x70d869a156d2a1b890bb3df62baf32f7n],
1296
+ [0x8000n, 0x31be135f97d08fd981231505542fcfa6n],
1297
+ [0x10000n, 0x9aa508b5b7a84e1c677de54f3e99bc9n],
1298
+ [0x20000n, 0x5d6af8dedb81196699c329225ee604n],
1299
+ [0x40000n, 0x2216e584f5fa1ea926041bedfe98n],
1300
+ [0x80000n, 0x48a170391f7dc42444e8fa2n]
1301
+ ];
1302
+ for (const [bit, mul] of steps) {
1303
+ if ((absTick & bit) !== 0n) ratio = ratio * mul >> 128n;
1304
+ }
1305
+ if (tick > 0) ratio = MAX_UINT256 / ratio;
1306
+ return (ratio >> 32n) + (ratio % (1n << 32n) === 0n ? 0n : 1n);
1307
+ }
1308
+ function snapDown(tick, spacing) {
1309
+ return Math.floor(tick / spacing) * spacing;
1310
+ }
1311
+ function snapUp(tick, spacing) {
1312
+ return Math.ceil(tick / spacing) * spacing;
1313
+ }
1314
+ function rangeFromPct(centerTick, pct, spacing) {
1315
+ if (!(pct > 0 && pct < 100)) throw new Error(`--range-pct must be in (0, 100) (got ${pct})`);
1316
+ const p = pct / 100;
1317
+ const lnBase = Math.log(1.0001);
1318
+ const down = Math.floor(Math.log(1 - p) / lnBase);
1319
+ const up = Math.ceil(Math.log(1 + p) / lnBase);
1320
+ const minAligned = snapUp(MIN_TICK, spacing);
1321
+ const maxAligned = snapDown(MAX_TICK, spacing);
1322
+ const tickLower = Math.max(minAligned, snapDown(centerTick + down, spacing));
1323
+ const tickUpper = Math.min(maxAligned, snapUp(centerTick + up, spacing));
1324
+ return { tickLower, tickUpper };
1325
+ }
1326
+ function liquidityForAmount0(sqrtA, sqrtB, amount0) {
1327
+ if (sqrtA > sqrtB) [sqrtA, sqrtB] = [sqrtB, sqrtA];
1328
+ const intermediate = sqrtA * sqrtB / Q96;
1329
+ return amount0 * intermediate / (sqrtB - sqrtA);
1330
+ }
1331
+ function liquidityForAmount1(sqrtA, sqrtB, amount1) {
1332
+ if (sqrtA > sqrtB) [sqrtA, sqrtB] = [sqrtB, sqrtA];
1333
+ return amount1 * Q96 / (sqrtB - sqrtA);
1334
+ }
1335
+ function liquidityForAmounts(sqrtP, sqrtA, sqrtB, amount0, amount1) {
1336
+ if (sqrtA > sqrtB) [sqrtA, sqrtB] = [sqrtB, sqrtA];
1337
+ if (sqrtP <= sqrtA) return liquidityForAmount0(sqrtA, sqrtB, amount0);
1338
+ if (sqrtP < sqrtB) {
1339
+ const l0 = liquidityForAmount0(sqrtP, sqrtB, amount0);
1340
+ const l1 = liquidityForAmount1(sqrtA, sqrtP, amount1);
1341
+ return l0 < l1 ? l0 : l1;
1342
+ }
1343
+ return liquidityForAmount1(sqrtA, sqrtB, amount1);
1344
+ }
1345
+ function amountsForLiquidity(sqrtP, sqrtA, sqrtB, liquidity) {
1346
+ if (sqrtA > sqrtB) [sqrtA, sqrtB] = [sqrtB, sqrtA];
1347
+ const a0 = (lo, hi) => (liquidity << 96n) * (hi - lo) / hi / lo;
1348
+ const a1 = (lo, hi) => liquidity * (hi - lo) / Q96;
1349
+ if (sqrtP <= sqrtA) return { amount0: a0(sqrtA, sqrtB), amount1: 0n };
1350
+ if (sqrtP < sqrtB) return { amount0: a0(sqrtP, sqrtB), amount1: a1(sqrtA, sqrtP) };
1351
+ return { amount0: 0n, amount1: a1(sqrtA, sqrtB) };
1352
+ }
1353
+ function token0ToToken1(amount0, sqrtP) {
1354
+ return amount0 * sqrtP / Q96 * sqrtP / Q96;
1355
+ }
1356
+ function token1ToToken0(amount1, sqrtP) {
1357
+ return amount1 * Q96 / sqrtP * Q96 / sqrtP;
1358
+ }
1359
+ function idealSwapFractionBps(sqrtP, tickLower, tickUpper, assetIsToken0) {
1360
+ const sqrtA = getSqrtRatioAtTick(tickLower);
1361
+ const sqrtB = getSqrtRatioAtTick(tickUpper);
1362
+ const { amount0, amount1 } = amountsForLiquidity(sqrtP, sqrtA, sqrtB, 10n ** 24n);
1363
+ const value0 = token0ToToken1(amount0, sqrtP);
1364
+ const total = value0 + amount1;
1365
+ if (total === 0n) return 0;
1366
+ const other = assetIsToken0 ? amount1 : value0;
1367
+ return Number((other * BPS + total / 2n) / total);
1368
+ }
1369
+ function estimateExpectedLiquidity(args) {
1370
+ const { sqrtPriceX96: sqrtP, assetIsToken0, deployable } = args;
1371
+ const swapped = deployable * BigInt(args.swapFractionBps) / BPS;
1372
+ const kept = deployable - swapped;
1373
+ let otherOut = assetIsToken0 ? token0ToToken1(swapped, sqrtP) : token1ToToken0(swapped, sqrtP);
1374
+ otherOut = otherOut * (FEE_DENOMINATOR - BigInt(args.poolFee)) / FEE_DENOMINATOR;
1375
+ const amount0 = assetIsToken0 ? kept : otherOut;
1376
+ const amount1 = assetIsToken0 ? otherOut : kept;
1377
+ return liquidityForAmounts(
1378
+ sqrtP,
1379
+ getSqrtRatioAtTick(args.tickLower),
1380
+ getSqrtRatioAtTick(args.tickUpper),
1381
+ amount0,
1382
+ amount1
1383
+ );
1384
+ }
1385
+ function derivedRerangeRange(center, halfWidthTicks, spacing) {
1386
+ const minAligned = snapUp(MIN_TICK, spacing);
1387
+ const maxAligned = snapDown(MAX_TICK, spacing);
1388
+ const lo = center - halfWidthTicks;
1389
+ const hi = center + halfWidthTicks;
1390
+ return {
1391
+ tickLower: lo <= minAligned ? minAligned : snapDown(lo, spacing),
1392
+ tickUpper: hi >= maxAligned ? maxAligned : snapUp(hi, spacing)
1393
+ };
1394
+ }
1395
+ function estimateSwapImpactBps(args) {
1396
+ const { sqrtPriceX96: sqrtP, liquidity: L } = args;
1397
+ const amt = args.amountIn * (FEE_DENOMINATOR - BigInt(args.poolFee)) / FEE_DENOMINATOR;
1398
+ if (amt === 0n) return 0;
1399
+ if (L === 0n || sqrtP === 0n) return 1e4;
1400
+ let num;
1401
+ let den;
1402
+ if (args.tokenInIsToken0) {
1403
+ const next = L * sqrtP * Q96 / (L * Q96 + amt * sqrtP);
1404
+ num = sqrtP - next;
1405
+ den = sqrtP;
1406
+ } else {
1407
+ const next = sqrtP + amt * Q96 / L;
1408
+ num = next - sqrtP;
1409
+ den = next;
1410
+ }
1411
+ const bps = (num * BPS + den - 1n) / den;
1412
+ return Number(bps > BPS ? BPS : bps);
1413
+ }
1414
+ var IMPACT_WARN_SHARE_BPS = 7000n;
1415
+ var POOL_SHARE_WARN_BPS = 8000n;
1416
+ function twapTickFromCumulatives(tickCumulatives, window) {
1417
+ const delta = tickCumulatives[1] - tickCumulatives[0];
1418
+ const w = BigInt(window);
1419
+ let avg = delta / w;
1420
+ if (delta < 0n && delta % w !== 0n) avg -= 1n;
1421
+ return Number(avg);
1422
+ }
1423
+ var UINT128_MAX = (1n << 128n) - 1n;
1424
+ function planConcentratedLiquidity(inputs, state) {
1425
+ const errors = [];
1426
+ const warnings = [];
1427
+ const asset = state.vaultAsset;
1428
+ const mp = state.marketParams;
1429
+ const sym = state.assetSymbol;
1430
+ const fmt = (v) => `${formatUnits2(v, state.assetDecimals)} ${sym}`;
1431
+ const named = [
1432
+ ["pool", inputs.pool],
1433
+ ["positionManager", inputs.positionManager],
1434
+ ["morpho", inputs.morpho],
1435
+ ["swapAdapter", inputs.swapAdapter],
1436
+ ["uniswapFactory", inputs.uniswapFactory]
1437
+ ];
1438
+ for (const [name, a] of named) {
1439
+ if (sameAddress(a, ZERO_ADDRESS)) {
1440
+ errors.push(`${withSelector("ZeroAddress()")}: ${name} is unset \u2014 no default on this network, pass it by flag`);
1441
+ }
1442
+ }
1443
+ if (inputs.collateralAmount === 0n || inputs.borrowAmount === 0n) {
1444
+ errors.push(`${withSelector("InvalidAmount()")}: --collateral-amount and --borrow-amount must both be > 0`);
1445
+ }
1446
+ if (!state.tierRegistry) {
1447
+ errors.push(
1448
+ `${withSelector("TierRegistryUnresolved()")}: the vault's governor names no TierRegistry, so no counterparty can be vouched for`
1449
+ );
1450
+ } else {
1451
+ const bound = [
1452
+ ["swap adapter", inputs.swapAdapter],
1453
+ ["position manager", inputs.positionManager],
1454
+ ["Morpho", inputs.morpho],
1455
+ ["Uniswap V3 factory", inputs.uniswapFactory]
1456
+ ];
1457
+ if (!sameAddress(mp.collateralToken, asset) && !sameAddress(mp.collateralToken, ZERO_ADDRESS)) {
1458
+ bound.push(["market collateral token", mp.collateralToken]);
1459
+ }
1460
+ for (const [label, a] of bound) {
1461
+ if (!sameAddress(a, ZERO_ADDRESS) && !isAllowed(state.allowed, a)) {
1462
+ errors.push(
1463
+ `${withSelector("CounterpartyNotAllowed(address,address)")}: ${label} ${a} is not counterparty-allowlisted on TierRegistry ${state.tierRegistry}`
1464
+ );
1465
+ }
1466
+ }
1467
+ }
1468
+ const pool = state.pool;
1469
+ let otherToken = ZERO_ADDRESS;
1470
+ let assetIsToken0 = false;
1471
+ let poolUsable = false;
1472
+ if (!pool.hasCode) {
1473
+ errors.push(`${withSelector("PoolNotFromFactory()")}: pool ${inputs.pool} holds no code`);
1474
+ } else {
1475
+ if (!sameAddress(pool.factoryPool, inputs.pool)) {
1476
+ errors.push(
1477
+ `${withSelector("PoolNotFromFactory()")}: factory ${inputs.uniswapFactory}.getPool(token0, token1, ${pool.fee}) = ${pool.factoryPool}, not ${inputs.pool}`
1478
+ );
1479
+ }
1480
+ if (sameAddress(pool.token0, asset)) {
1481
+ assetIsToken0 = true;
1482
+ otherToken = pool.token1;
1483
+ } else if (sameAddress(pool.token1, asset)) {
1484
+ otherToken = pool.token0;
1485
+ } else {
1486
+ errors.push(
1487
+ `${withSelector("PoolAssetMismatch()")}: pool ${inputs.pool} trades ${pool.token0}/${pool.token1}; neither is the vault asset ${asset} (${sym})`
1488
+ );
1489
+ }
1490
+ if (!sameAddress(otherToken, ZERO_ADDRESS)) {
1491
+ poolUsable = true;
1492
+ if (state.tierRegistry && !isAllowed(state.allowed, otherToken)) {
1493
+ errors.push(
1494
+ `${withSelector("CounterpartyNotAllowed(address,address)")}: the pool's other token ${otherToken} is not counterparty-allowlisted on TierRegistry ${state.tierRegistry}`
1495
+ );
1496
+ }
1497
+ }
1498
+ }
1499
+ const unknownMarket = sameAddress(mp.loanToken, ZERO_ADDRESS) && mp.lltv === 0n;
1500
+ if (unknownMarket) {
1501
+ errors.push(
1502
+ `${withSelector("MarketNotCreated()")}: market ${inputs.marketId} does not exist on Morpho ${inputs.morpho} (idToMarketParams is empty)`
1503
+ );
1504
+ } else {
1505
+ if (!sameAddress(mp.loanToken, asset)) {
1506
+ errors.push(
1507
+ `${withSelector("LoanAssetMismatch()")}: market ${inputs.marketId} lends ${mp.loanToken}, not the vault asset ${asset} (${sym})`
1508
+ );
1509
+ }
1510
+ const derived = marketIdOf(mp);
1511
+ if (derived.toLowerCase() !== inputs.marketId.toLowerCase()) {
1512
+ errors.push(`market params returned for ${inputs.marketId} hash to ${derived} \u2014 not the market you named`);
1513
+ }
1514
+ if (state.market.lastUpdate === 0n) {
1515
+ errors.push(`${withSelector("MarketNotCreated()")}: market ${inputs.marketId} has never been created`);
1516
+ }
1517
+ if (poolUsable && sameAddress(mp.collateralToken, otherToken)) {
1518
+ errors.push(
1519
+ `${withSelector("CollateralAssetMismatch()")}: the market's collateral ${mp.collateralToken} is the pool's volatile leg \u2014 CL borrows the vault asset against the vault asset or an ERC-4626 wrapper of it (e.g. a USDG-loan market with USDG/sUSDG collateral)`
1520
+ );
1521
+ } else if (!sameAddress(mp.collateralToken, asset)) {
1522
+ const wa = state.collateral.wrapperAsset;
1523
+ if (!wa || !sameAddress(wa, asset)) {
1524
+ errors.push(
1525
+ `${withSelector("CollateralAssetMismatch()")}: the market's collateral ${mp.collateralToken} is neither the vault asset nor an ERC-4626 wrapper of it` + (wa ? ` (its asset() is ${wa})` : " (no ERC-4626 asset())")
1526
+ );
1527
+ }
1528
+ }
1529
+ }
1530
+ const lendable = state.market.totalSupplyAssets > state.market.totalBorrowAssets ? state.market.totalSupplyAssets - state.market.totalBorrowAssets : 0n;
1531
+ if (!unknownMarket && inputs.borrowAmount > lendable) {
1532
+ errors.push(
1533
+ `${withSelector("BorrowExceedsLiquidity()")}: borrow ${fmt(inputs.borrowAmount)} exceeds the market's lendable ${fmt(lendable)}`
1534
+ );
1535
+ }
1536
+ let ltvBps = 0n;
1537
+ const lltvBps = mp.lltv * BPS / 10n ** 18n;
1538
+ if (!unknownMarket && inputs.collateralAmount > 0n) {
1539
+ const value = sameAddress(mp.collateralToken, asset) ? inputs.collateralAmount : state.collateral.value;
1540
+ if (value === null || value === 0n) {
1541
+ if (!sameAddress(mp.collateralToken, asset)) {
1542
+ errors.push(
1543
+ `${withSelector("CollateralValueUnavailable()")}: ${mp.collateralToken}.previewRedeem(previewDeposit(${inputs.collateralAmount})) is unreadable or zero`
1544
+ );
1545
+ }
1546
+ } else {
1547
+ ltvBps = inputs.borrowAmount * BPS / value;
1548
+ if (lltvBps < MIN_LLTV_BUFFER_BPS || ltvBps > lltvBps - MIN_LLTV_BUFFER_BPS) {
1549
+ const maxLtv = lltvBps >= MIN_LLTV_BUFFER_BPS ? lltvBps - MIN_LLTV_BUFFER_BPS : 0n;
1550
+ const maxBorrow = value * maxLtv / BPS;
1551
+ errors.push(
1552
+ `${withSelector("LtvInsideLiquidationBuffer()")}: LTV ${ltvBps} bps vs market LLTV ${lltvBps} bps \u2014 must be \u2264 ${maxLtv} bps (LLTV \u2212 ${MIN_LLTV_BUFFER_BPS} bps buffer); max borrow against ${fmt(inputs.collateralAmount)} collateral \u2248 ${fmt(maxBorrow)}`
1553
+ );
1554
+ }
1555
+ }
1556
+ }
1557
+ const spacing = pool.tickSpacing;
1558
+ let tickLower = 0;
1559
+ let tickUpper = 0;
1560
+ let rangeOk = false;
1561
+ if (poolUsable) {
1562
+ if ("pct" in inputs.range) {
1563
+ try {
1564
+ ({ tickLower, tickUpper } = rangeFromPct(pool.tick, inputs.range.pct, spacing));
1565
+ } catch (e) {
1566
+ errors.push(e.message);
1567
+ }
1568
+ } else {
1569
+ ({ tickLower, tickUpper } = inputs.range);
1570
+ }
1571
+ if (tickLower >= tickUpper || spacing <= 0 || tickLower % spacing !== 0 || tickUpper % spacing !== 0) {
1572
+ errors.push(
1573
+ `${withSelector("InvalidTickRange()")}: [${tickLower}, ${tickUpper}] must be ordered, non-empty and multiples of tickSpacing ${spacing}`
1574
+ );
1575
+ } else if (tickLower < MIN_TICK || tickUpper > MAX_TICK) {
1576
+ errors.push(`tick range [${tickLower}, ${tickUpper}] leaves the V3 domain [${MIN_TICK}, ${MAX_TICK}] \u2014 the mint would revert`);
1577
+ } else {
1578
+ rangeOk = true;
1579
+ }
1580
+ }
1581
+ const swapFractionBps = inputs.swapFractionBps ?? (rangeOk ? idealSwapFractionBps(pool.sqrtPriceX96, tickLower, tickUpper, assetIsToken0) : 0);
1582
+ const poolShareCap = pool.liquidity * MAX_POOL_SHARE_BPS / BPS;
1583
+ let expectedLiquidity = inputs.expectedLiquidity ?? 0n;
1584
+ if (inputs.expectedLiquidity === void 0 && rangeOk && pool.sqrtPriceX96 > 0n) {
1585
+ expectedLiquidity = estimateExpectedLiquidity({
1586
+ sqrtPriceX96: pool.sqrtPriceX96,
1587
+ tickLower,
1588
+ tickUpper,
1589
+ assetIsToken0,
1590
+ deployable: inputs.borrowAmount,
1591
+ swapFractionBps,
1592
+ poolFee: pool.fee
1593
+ });
1594
+ }
1595
+ if (poolUsable && rangeOk) {
1596
+ if (expectedLiquidity === 0n) {
1597
+ errors.push(`${withSelector("InvalidAmount()")}: expectedLiquidity is 0 \u2014 the borrow is too small to mint in this range`);
1598
+ } else if (expectedLiquidity > UINT128_MAX) {
1599
+ errors.push(`expectedLiquidity ${expectedLiquidity} does not fit uint128`);
1600
+ } else if (expectedLiquidity > poolShareCap) {
1601
+ const maxBorrow = inputs.borrowAmount * poolShareCap / expectedLiquidity;
1602
+ errors.push(
1603
+ `${withSelector("PositionExceedsPoolShareCap()")}: expected liquidity ${expectedLiquidity} exceeds ${MAX_POOL_SHARE_BPS} bps of the pool's in-range liquidity (${pool.liquidity} \u2192 cap ${poolShareCap}); at this range the borrow must stay under \u2248 ${fmt(maxBorrow)}`
1604
+ );
1605
+ }
1606
+ }
1607
+ const bounds = [
1608
+ [inputs.twapWindow < MIN_TWAP_WINDOW, `--twap-window ${inputs.twapWindow} < MIN_TWAP_WINDOW ${MIN_TWAP_WINDOW}`],
1609
+ [
1610
+ inputs.maxTwapDeviationBps === 0 || inputs.maxTwapDeviationBps > MAX_TWAP_DEVIATION_BPS,
1611
+ `--max-twap-deviation ${inputs.maxTwapDeviationBps} must be in [1, ${MAX_TWAP_DEVIATION_BPS}]`
1612
+ ],
1613
+ [
1614
+ inputs.mintSlippageBps === 0 || inputs.mintSlippageBps > MAX_SLIPPAGE_BPS,
1615
+ `--mint-slippage-bps ${inputs.mintSlippageBps} must be in [1, ${MAX_SLIPPAGE_BPS}]`
1616
+ ],
1617
+ [
1618
+ inputs.settleSlippageBps === 0 || inputs.settleSlippageBps > MAX_SLIPPAGE_BPS,
1619
+ `--settle-slippage-bps ${inputs.settleSlippageBps} must be in [1, ${MAX_SLIPPAGE_BPS}] (0 is not a legal init value)`
1620
+ ],
1621
+ [swapFractionBps < 0 || swapFractionBps > 1e4, `--swap-fraction-bps ${swapFractionBps} must be in [0, 10000]`]
1622
+ ];
1623
+ for (const [bad, msg] of bounds) if (bad) errors.push(`${withSelector("InvalidBound()")}: ${msg}`);
1624
+ const halfWidthTicks = inputs.rerange.halfWidthTicks ?? Math.max(spacing, Math.ceil((tickUpper - tickLower) / 2));
1625
+ let rerangeSwapFraction = swapFractionBps;
1626
+ if (inputs.rerange.swapFractionBps !== void 0) {
1627
+ rerangeSwapFraction = inputs.rerange.swapFractionBps;
1628
+ } else if (poolUsable && rangeOk && pool.sqrtPriceX96 > 0n && halfWidthTicks >= spacing && halfWidthTicks <= MAX_HALF_WIDTH_TICKS) {
1629
+ const centred = derivedRerangeRange(pool.tick, halfWidthTicks, spacing);
1630
+ rerangeSwapFraction = idealSwapFractionBps(pool.sqrtPriceX96, centred.tickLower, centred.tickUpper, assetIsToken0);
1631
+ }
1632
+ if (poolUsable && rangeOk) {
1633
+ const policy = [
1634
+ [halfWidthTicks < spacing, `--rerange-half-width ${halfWidthTicks} < tickSpacing ${spacing}`],
1635
+ [
1636
+ halfWidthTicks * 2 < tickUpper - tickLower,
1637
+ `--rerange-half-width ${halfWidthTicks} \xD7 2 is narrower than the initial range (${tickUpper - tickLower} ticks)`
1638
+ ],
1639
+ [halfWidthTicks > MAX_HALF_WIDTH_TICKS, `--rerange-half-width ${halfWidthTicks} > ${MAX_HALF_WIDTH_TICKS}`]
1640
+ ];
1641
+ for (const [bad, msg] of policy) if (bad) errors.push(`${withSelector("InvalidRerangePolicy()")}: ${msg}`);
1642
+ }
1643
+ const policyBounds = [
1644
+ [
1645
+ inputs.rerange.triggerBps === 0 || inputs.rerange.triggerBps > 1e4,
1646
+ `--rerange-trigger-bps ${inputs.rerange.triggerBps} must be in [1, 10000]`
1647
+ ],
1648
+ [inputs.rerange.maxReranges > MAX_RERANGE_LIMIT, `--max-reranges ${inputs.rerange.maxReranges} > ${MAX_RERANGE_LIMIT}`],
1649
+ [
1650
+ inputs.rerange.slippageBps === 0 || inputs.rerange.slippageBps > MAX_SLIPPAGE_BPS,
1651
+ `--rerange-slippage-bps ${inputs.rerange.slippageBps} must be in [1, ${MAX_SLIPPAGE_BPS}]`
1652
+ ],
1653
+ [
1654
+ rerangeSwapFraction < 0 || rerangeSwapFraction > 1e4,
1655
+ `--rerange-swap-fraction-bps ${rerangeSwapFraction} must be in [0, 10000]`
1656
+ ]
1657
+ ];
1658
+ for (const [bad, msg] of policyBounds) if (bad) errors.push(`${withSelector("InvalidRerangePolicy()")}: ${msg}`);
1659
+ if (inputs.collateralAmount > 0n && state.vaultBalance < inputs.collateralAmount) {
1660
+ errors.push(
1661
+ `vault holds ${fmt(state.vaultBalance)} but execute pulls ${fmt(inputs.collateralAmount)} as collateral (amounts are human units)`
1662
+ );
1663
+ }
1664
+ if (poolUsable) {
1665
+ if (pool.observationCardinality < 2 || pool.twapTick === null) {
1666
+ warnings.push(
1667
+ `pool ${inputs.pool} cannot serve a ${inputs.twapWindow}s TWAP right now (observation cardinality ${pool.observationCardinality}) \u2014 execute() reverts ${withSelector("TwapUnavailable()")} until it can; raise it with pool.increaseObservationCardinalityNext(n) and wait out the window`
1668
+ );
1669
+ } else {
1670
+ const dev = Math.abs(pool.tick - pool.twapTick);
1671
+ if (dev > inputs.maxTwapDeviationBps) {
1672
+ warnings.push(
1673
+ `spot tick ${pool.tick} is ${dev} ticks from the ${inputs.twapWindow}s TWAP ${pool.twapTick} (bound ${inputs.maxTwapDeviationBps}) \u2014 execute() would revert ${withSelector("SpotOutsideTwapBound()")} if it ran now`
1674
+ );
1675
+ }
1676
+ }
1677
+ }
1678
+ if (poolUsable && rangeOk && pool.sqrtPriceX96 > 0n && expectedLiquidity > 0n && expectedLiquidity <= UINT128_MAX) {
1679
+ const sqrtA = getSqrtRatioAtTick(tickLower);
1680
+ const sqrtB = getSqrtRatioAtTick(tickUpper);
1681
+ const otherIsToken0 = !assetIsToken0;
1682
+ const pick = (a) => otherIsToken0 ? a.amount0 : a.amount1;
1683
+ const legNow = pick(amountsForLiquidity(pool.sqrtPriceX96, sqrtA, sqrtB, expectedLiquidity));
1684
+ const edgeSqrt = otherIsToken0 ? sqrtA : sqrtB;
1685
+ const legEdge = pick(amountsForLiquidity(edgeSqrt, sqrtA, sqrtB, expectedLiquidity));
1686
+ const impact = (sqrt, amountIn, tokenInIsToken0) => estimateSwapImpactBps({ sqrtPriceX96: sqrt, liquidity: pool.liquidity, amountIn, tokenInIsToken0, poolFee: pool.fee });
1687
+ const settleNow = impact(pool.sqrtPriceX96, legNow, otherIsToken0);
1688
+ const settleEdge = impact(edgeSqrt, legEdge, otherIsToken0);
1689
+ const settle = BigInt(inputs.settleSlippageBps);
1690
+ const approx = `(constant in-range liquidity ${pool.liquidity}, no tick crossings, pool route only \u2014 an estimate)`;
1691
+ const suggest = (bps) => Math.min(MAX_SLIPPAGE_BPS, Math.ceil(bps * 1e4 / Number(IMPACT_WARN_SHARE_BPS)));
1692
+ if (BigInt(settleNow) * BPS > settle * IMPACT_WARN_SHARE_BPS) {
1693
+ warnings.push(
1694
+ `settle sells the volatile leg (~${legNow} base units of ${otherToken} at today's price) through this pool with an estimated ${settleNow} bps price impact ${approx} \u2014 more than 70% of --settle-slippage-bps ${inputs.settleSlippageBps}, so settle() can revert on its own slippage floor. Settle slippage can only be tightened after init: consider --settle-slippage-bps ${suggest(settleNow)} or a smaller borrow`
1695
+ );
1696
+ } else if (BigInt(settleEdge) * BPS > settle * BPS) {
1697
+ warnings.push(
1698
+ `if price reaches the range edge on the volatile side, settle sells the whole position (~${legEdge} base units of ${otherToken}) with an estimated ${settleEdge} bps impact ${approx} \u2014 above --settle-slippage-bps ${inputs.settleSlippageBps}, which can only be tightened after init; consider --settle-slippage-bps ${suggest(settleEdge)} or a smaller borrow`
1699
+ );
1700
+ }
1701
+ const swapped = inputs.borrowAmount * BigInt(swapFractionBps) / BPS;
1702
+ const mintImpact = impact(pool.sqrtPriceX96, swapped, assetIsToken0);
1703
+ if (BigInt(mintImpact) * BPS > BigInt(inputs.mintSlippageBps) * IMPACT_WARN_SHARE_BPS) {
1704
+ warnings.push(
1705
+ `execute swaps ${fmt(swapped)} into ${otherToken} through this pool with an estimated ${mintImpact} bps price impact ${approx} \u2014 more than 70% of --mint-slippage-bps ${inputs.mintSlippageBps}; execute() can revert on its slippage floor. Consider --mint-slippage-bps ${suggest(mintImpact)} or a smaller borrow`
1706
+ );
1707
+ }
1708
+ if (poolShareCap > 0n && expectedLiquidity <= poolShareCap && expectedLiquidity * BPS > poolShareCap * POOL_SHARE_WARN_BPS) {
1709
+ const pct = Number(expectedLiquidity * 1000n / poolShareCap) / 10;
1710
+ warnings.push(
1711
+ `expected liquidity ${expectedLiquidity} is ${pct}% of the pool-share cap ${poolShareCap} (${MAX_POOL_SHARE_BPS} bps of in-range liquidity ${pool.liquidity}). execute() re-checks the ACTUAL minted liquidity against the pool as it is then; a small drop in pool liquidity (or a mint above the estimate) reverts ${withSelector("PositionExceedsPoolShareCap()")} \u2014 leave more headroom`
1712
+ );
1713
+ }
1714
+ }
1715
+ if (errors.length > 0) return { plan: null, errors, warnings };
1716
+ const params = {
1717
+ pool: inputs.pool,
1718
+ positionManager: inputs.positionManager,
1719
+ uniswapFactory: inputs.uniswapFactory,
1720
+ swapAdapter: inputs.swapAdapter,
1721
+ morpho: inputs.morpho,
1722
+ marketParams: mp,
1723
+ collateralAmount: inputs.collateralAmount,
1724
+ borrowAmount: inputs.borrowAmount,
1725
+ tickLower,
1726
+ tickUpper,
1727
+ expectedLiquidity,
1728
+ swapFractionBps: BigInt(swapFractionBps),
1729
+ twapWindow: inputs.twapWindow,
1730
+ maxTwapDeviationBps: BigInt(inputs.maxTwapDeviationBps),
1731
+ mintSlippageBps: BigInt(inputs.mintSlippageBps),
1732
+ rerange: {
1733
+ halfWidthTicks,
1734
+ triggerBps: BigInt(inputs.rerange.triggerBps),
1735
+ minInterval: inputs.rerange.minInterval,
1736
+ maxReranges: BigInt(inputs.rerange.maxReranges),
1737
+ slippageBps: BigInt(inputs.rerange.slippageBps),
1738
+ swapFractionBps: BigInt(rerangeSwapFraction)
1739
+ },
1740
+ settleSlippageBps: BigInt(inputs.settleSlippageBps),
1741
+ settleDeadline: inputs.settleDeadline,
1742
+ swapExtraData: inputs.swapExtraData ?? v3SingleHopExtraData(pool.fee)
1743
+ };
1744
+ return {
1745
+ plan: {
1746
+ params,
1747
+ asset,
1748
+ otherToken,
1749
+ assetIsToken0,
1750
+ info: { ltvBps, lltvBps, poolShareCap, spotTick: pool.tick, twapTick: pool.twapTick }
1751
+ },
1752
+ errors,
1753
+ warnings
1754
+ };
1755
+ }
1756
+
920
1757
  // src/lib/template-encoder.ts
921
1758
  var ZERO = "0x0000000000000000000000000000000000000000";
922
1759
  function encodeV3Path(tokens, fees) {
@@ -933,13 +1770,13 @@ function encodeV3Path(tokens, fees) {
933
1770
  function buildSwapExtraData(network, tokenIn, tokenOut, feeTier, hop, perHopSlippageBps = 100) {
934
1771
  if (hop) {
935
1772
  const path = encodeV3Path([tokenIn, hop.via, tokenOut], [hop.feeIn, hop.feeOut]);
936
- const encoded2 = encodeAbiParameters9(
1773
+ const encoded2 = encodeAbiParameters12(
937
1774
  [{ type: "bytes" }, { type: "uint16" }],
938
1775
  [path, perHopSlippageBps]
939
1776
  );
940
1777
  return `0x01${encoded2.slice(2)}`;
941
1778
  }
942
- const encoded = encodeAbiParameters9([{ type: "uint24" }], [feeTier]);
1779
+ const encoded = encodeAbiParameters12([{ type: "uint24" }], [feeTier]);
943
1780
  return `0x00${encoded.slice(2)}`;
944
1781
  }
945
1782
  function parseSwapRouteSpec(spec, token) {
@@ -973,7 +1810,7 @@ function parseSwapRouteSpec(spec, token) {
973
1810
  let currency;
974
1811
  if (c === "eth" || c === "native") currency = ZERO;
975
1812
  else if (c === "self") currency = token;
976
- else if (isAddress(currencyRaw.trim())) currency = currencyRaw.trim();
1813
+ else if (isAddress2(currencyRaw.trim())) currency = currencyRaw.trim();
977
1814
  else throw new Error(`bad v4path currency '${currencyRaw}' in '${spec}' (use eth/native/self/0x-address)`);
978
1815
  return { currency, fee, tickSpacing };
979
1816
  });
@@ -996,14 +1833,14 @@ function computeProposalAssetChecks(templateKey, opts) {
996
1833
  const token = opts.token || "USDC";
997
1834
  const asset = resolveToken(token);
998
1835
  const decimals = assetDecimalsForSymbol(token);
999
- return [{ asset, amount: parseUnits(opts.amount, decimals), label: token.toUpperCase() }];
1836
+ return [{ asset, amount: parseUnits2(opts.amount, decimals), label: token.toUpperCase() }];
1000
1837
  }
1001
1838
  if (templateKey === "venice-inference") {
1002
1839
  if (!opts.amount) return [];
1003
1840
  const assetSymbol = opts.asset || "USDC";
1004
1841
  const asset = resolveToken(assetSymbol);
1005
1842
  const decimals = assetDecimalsForSymbol(assetSymbol);
1006
- return [{ asset, amount: parseUnits(opts.amount, decimals), label: assetSymbol.toUpperCase() }];
1843
+ return [{ asset, amount: parseUnits2(opts.amount, decimals), label: assetSymbol.toUpperCase() }];
1007
1844
  }
1008
1845
  if (templateKey === "aerodrome-lp") {
1009
1846
  if (!opts.tokenA || !opts.tokenB || !opts.amountA || !opts.amountB) return [];
@@ -1013,7 +1850,7 @@ function computeProposalAssetChecks(templateKey, opts) {
1013
1850
  if (!opts.amount) return [];
1014
1851
  return [{
1015
1852
  asset: TOKENS().WETH,
1016
- amount: parseUnits(opts.amount, 18),
1853
+ amount: parseUnits2(opts.amount, 18),
1017
1854
  label: "WETH"
1018
1855
  }];
1019
1856
  }
@@ -1022,14 +1859,25 @@ function computeProposalAssetChecks(templateKey, opts) {
1022
1859
  const assetSymbol = opts.asset || defaultPortfolioAsset();
1023
1860
  const asset = resolveToken(assetSymbol);
1024
1861
  const decimals = assetDecimalsForSymbol(assetSymbol);
1025
- return [{ asset, amount: parseUnits(opts.amount, decimals), label: assetSymbol.toUpperCase() }];
1862
+ return [{ asset, amount: parseUnits2(opts.amount, decimals), label: assetSymbol.toUpperCase() }];
1026
1863
  }
1027
1864
  if (templateKey === "hyperliquid-perp" || templateKey === "hyperliquid-grid") {
1028
1865
  if (!opts.amount) return [];
1029
1866
  const token = opts.token || "USDC";
1030
1867
  const asset = resolveToken(token);
1031
1868
  const decimals = assetDecimalsForSymbol(token);
1032
- return [{ asset, amount: parseUnits(opts.amount, decimals), label: token.toUpperCase() }];
1869
+ return [{ asset, amount: parseUnits2(opts.amount, decimals), label: token.toUpperCase() }];
1870
+ }
1871
+ if (templateKey === "lighter-perp") {
1872
+ const human = opts.deposit ?? opts.amount;
1873
+ if (!human) return [];
1874
+ let amount;
1875
+ try {
1876
+ amount = usdgToTicks(human);
1877
+ } catch {
1878
+ return [];
1879
+ }
1880
+ return [{ asset: LIGHTER_USDG, amount, label: "USDG" }];
1033
1881
  }
1034
1882
  return [];
1035
1883
  }
@@ -1048,11 +1896,11 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1048
1896
  const underlying = resolveToken(token);
1049
1897
  const mToken = resolveMToken(token);
1050
1898
  const decimals = assetDecimalsForSymbol(token);
1051
- const supplyAmount = parseUnits(opts.amount, decimals);
1052
- const minRedeem = parseUnits(opts.minRedeem || opts.amount, decimals);
1899
+ const supplyAmount = parseUnits2(opts.amount, decimals);
1900
+ const minRedeem = parseUnits2(opts.minRedeem || opts.amount, decimals);
1053
1901
  const isNativeEthMarket = token.toUpperCase() !== "USDC";
1054
1902
  return {
1055
- initData: buildInitData(underlying, mToken, supplyAmount, minRedeem, isNativeEthMarket),
1903
+ initData: buildInitData3(underlying, mToken, supplyAmount, minRedeem, isNativeEthMarket),
1056
1904
  asset: underlying,
1057
1905
  assetAmount: supplyAmount
1058
1906
  };
@@ -1067,7 +1915,7 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1067
1915
  const vvv = VENICE().VVV;
1068
1916
  const isDirect = asset.toLowerCase() === vvv.toLowerCase();
1069
1917
  const decimals = assetDecimalsForSymbol(assetSymbol);
1070
- const assetAmount = parseUnits(opts.amount, decimals);
1918
+ const assetAmount = parseUnits2(opts.amount, decimals);
1071
1919
  const agent = opts.agent || resolved?.veniceAgent;
1072
1920
  if (!agent) {
1073
1921
  throw new Error(
@@ -1078,7 +1926,7 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1078
1926
  let minVVV = 0n;
1079
1927
  if (!isDirect) {
1080
1928
  if (opts.minVvv) {
1081
- minVVV = parseUnits(opts.minVvv, 18);
1929
+ minVVV = parseUnits2(opts.minVvv, 18);
1082
1930
  } else if (resolved?.veniceMinVVV !== void 0) {
1083
1931
  minVVV = resolved.veniceMinVVV;
1084
1932
  } else {
@@ -1101,7 +1949,7 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1101
1949
  singleHop: isSingleHop
1102
1950
  };
1103
1951
  return {
1104
- initData: buildInitData2(params),
1952
+ initData: buildInitData4(params),
1105
1953
  asset,
1106
1954
  assetAmount
1107
1955
  };
@@ -1121,10 +1969,10 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1121
1969
  );
1122
1970
  }
1123
1971
  const { decimalsA, decimalsB } = resolved.aerodromeDecimals;
1124
- const amountA = parseUnits(opts.amountA, decimalsA);
1125
- const amountB = parseUnits(opts.amountB, decimalsB);
1126
- const minAOut = parseUnits(opts.minAOut || "0", decimalsA);
1127
- const minBOut = parseUnits(opts.minBOut || "0", decimalsB);
1972
+ const amountA = parseUnits2(opts.amountA, decimalsA);
1973
+ const amountB = parseUnits2(opts.amountB, decimalsB);
1974
+ const minAOut = parseUnits2(opts.minAOut || "0", decimalsA);
1975
+ const minBOut = parseUnits2(opts.minBOut || "0", decimalsB);
1128
1976
  const params = {
1129
1977
  tokenA,
1130
1978
  tokenB,
@@ -1142,14 +1990,14 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1142
1990
  minAmountBOut: minBOut
1143
1991
  };
1144
1992
  return {
1145
- initData: buildInitData3(params),
1993
+ initData: buildInitData5(params),
1146
1994
  asset: tokenA,
1147
1995
  assetAmount: amountA,
1148
1996
  extraApprovals: [{ token: tokenB, amount: amountB }]
1149
1997
  };
1150
1998
  }
1151
1999
  if (templateKey === "wsteth-moonwell") {
1152
- const supplyAmount = opts.amount ? parseUnits(opts.amount, 18) : 0n;
2000
+ const supplyAmount = opts.amount ? parseUnits2(opts.amount, 18) : 0n;
1153
2001
  const slippageBps = BigInt(opts.slippage || "500");
1154
2002
  const ONE = 10n ** 18n;
1155
2003
  const minWstethOutPerWeth = ONE * (10000n - slippageBps) / 10000n;
@@ -1167,7 +2015,7 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1167
2015
  deadlineOffset: 300n
1168
2016
  };
1169
2017
  return {
1170
- initData: buildInitData4(params),
2018
+ initData: buildInitData6(params),
1171
2019
  asset: TOKENS().WETH,
1172
2020
  assetAmount: supplyAmount
1173
2021
  };
@@ -1184,10 +2032,10 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1184
2032
  const token = opts.token || "USDC";
1185
2033
  const underlying = resolveToken(token);
1186
2034
  const decimals = assetDecimalsForSymbol(token);
1187
- const amount = parseUnits(opts.amount, decimals);
1188
- const minRedeemAmount = parseUnits(opts.minRedeem || opts.amount, decimals);
2035
+ const amount = parseUnits2(opts.amount, decimals);
2036
+ const minRedeemAmount = parseUnits2(opts.minRedeem || opts.amount, decimals);
1189
2037
  return {
1190
- initData: buildInitData5(underlying, opts.mamoFactory, minRedeemAmount),
2038
+ initData: buildInitData7(underlying, opts.mamoFactory, minRedeemAmount),
1191
2039
  asset: underlying,
1192
2040
  assetAmount: amount
1193
2041
  };
@@ -1226,12 +2074,12 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1226
2074
  const assetSymbol = opts.asset || defaultPortfolioAsset();
1227
2075
  const asset = resolveToken(assetSymbol);
1228
2076
  const decimals = assetDecimalsForSymbol(assetSymbol);
1229
- const totalAmount = parseUnits(opts.amount, decimals);
2077
+ const totalAmount = parseUnits2(opts.amount, decimals);
1230
2078
  const maxSlippageBps = Number(opts.maxSlippage || "500");
1231
2079
  const feeTier = opts.feeTier || "3000";
1232
2080
  const tokenSpecs = opts.tokens.split(",").map((t) => t.trim());
1233
2081
  const tokenAddrs = tokenSpecs.map((trimmed) => {
1234
- if (isAddress(trimmed)) return trimmed;
2082
+ if (isAddress2(trimmed)) return trimmed;
1235
2083
  const allTokens = tokens;
1236
2084
  const resolvedAddr = allTokens[trimmed.toUpperCase()];
1237
2085
  if (resolvedAddr && resolvedAddr !== ZERO) return resolvedAddr;
@@ -1314,14 +2162,14 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1314
2162
  console.log(chalk.dim(` ${token.slice(0, 10)}... \u2192 ${route.routeDesc}`));
1315
2163
  const priceDecimals2 = priceDecimalOverrides[i] ? Number(priceDecimalOverrides[i]) : 8;
1316
2164
  let feed = feedOverrides[i];
1317
- if (feed && !isAddress(feed)) {
2165
+ if (feed && !isAddress2(feed)) {
1318
2166
  console.error(chalk.red(`Bad --feeds entry for ${tokenSpecs[i]}: '${feed}' is not a 0x-prefixed AggregatorV3 address.`));
1319
2167
  process.exit(1);
1320
2168
  }
1321
2169
  if (!feed) {
1322
2170
  const sym = tokenSpecs[i].toUpperCase();
1323
2171
  const feedKey = sym === "WETH" || sym === "ETH" ? "ETH_USD_FEED" : `${sym}_USD_FEED`;
1324
- feed = isAddress(tokenSpecs[i]) ? void 0 : chainlink[feedKey];
2172
+ feed = isAddress2(tokenSpecs[i]) ? void 0 : chainlink[feedKey];
1325
2173
  }
1326
2174
  if (!feed || feed === ZERO) {
1327
2175
  console.error(chalk.red(`No Chainlink push feed for ${tokenSpecs[i]} on ${network}. Pass --feeds <feedAddr,...> to supply AggregatorV3 addresses (every slot must be non-zero).`));
@@ -1336,7 +2184,7 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1336
2184
  });
1337
2185
  }
1338
2186
  return {
1339
- initData: buildInitData6(asset, swapAdapter, allocations, totalAmount, maxSlippageBps),
2187
+ initData: buildInitData8(asset, swapAdapter, allocations, totalAmount, maxSlippageBps),
1340
2188
  asset,
1341
2189
  assetAmount: totalAmount
1342
2190
  };
@@ -1345,13 +2193,13 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1345
2193
  const token = opts.token || "USDC";
1346
2194
  const asset = resolveToken(token);
1347
2195
  const decimals = assetDecimalsForSymbol(token);
1348
- const depositAmount = opts.amount ? parseUnits(opts.amount, decimals) : 0n;
2196
+ const depositAmount = opts.amount ? parseUnits2(opts.amount, decimals) : 0n;
1349
2197
  const leverage = Number(opts.leverage || "10");
1350
2198
  const assetIndex = Number(opts.assetIndex || "0");
1351
- const maxPosition = parseUnits(opts.maxPosition || "100000", decimals);
2199
+ const maxPosition = parseUnits2(opts.maxPosition || "100000", decimals);
1352
2200
  const maxTradesDay = Number(opts.maxTradesPerDay || "50");
1353
2201
  return {
1354
- initData: buildInitData7(asset, depositAmount, assetIndex, leverage, maxPosition, maxTradesDay),
2202
+ initData: buildInitData9(asset, depositAmount, assetIndex, leverage, maxPosition, maxTradesDay),
1355
2203
  asset,
1356
2204
  assetAmount: depositAmount
1357
2205
  };
@@ -1360,68 +2208,139 @@ async function buildInitDataForTemplate(templateKey, opts, vault, resolved) {
1360
2208
  const token = opts.token || "USDC";
1361
2209
  const asset = resolveToken(token);
1362
2210
  const decimals = assetDecimalsForSymbol(token);
1363
- const depositAmount = opts.amount ? parseUnits(opts.amount, decimals) : 0n;
2211
+ const depositAmount = opts.amount ? parseUnits2(opts.amount, decimals) : 0n;
1364
2212
  const leverage = Number(opts.leverage || "5");
1365
- const maxOrderSize = parseUnits(opts.maxOrderSize || "10000", decimals);
2213
+ const maxOrderSize = parseUnits2(opts.maxOrderSize || "10000", decimals);
1366
2214
  const maxOrdersPerTick = Number(opts.maxOrdersPerTick || "20");
1367
2215
  const assetIndices = (opts.assetIndices || "0").split(",").map((s) => Number(s.trim())).filter((n) => !Number.isNaN(n));
1368
2216
  return {
1369
- initData: buildInitData8(asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices),
2217
+ initData: buildInitData10(asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices),
1370
2218
  asset,
1371
2219
  assetAmount: depositAmount
1372
2220
  };
1373
2221
  }
2222
+ if (templateKey === "lighter-perp") {
2223
+ const params = parseLighterTemplateFlags(
2224
+ {
2225
+ pubkey: opts.pubkey,
2226
+ keyIndex: opts.keyIndex,
2227
+ markets: opts.markets,
2228
+ deposit: opts.deposit,
2229
+ amount: opts.amount
2230
+ },
2231
+ resolved?.lighterSavedKey
2232
+ );
2233
+ return {
2234
+ initData: buildInitData(params),
2235
+ asset: LIGHTER_USDG,
2236
+ assetAmount: params.depositAmount
2237
+ };
2238
+ }
2239
+ if (templateKey === "launchpad") {
2240
+ if (!resolved?.launchpad) {
2241
+ throw new Error("launchpad: missing resolved chain inputs \u2014 run resolveChainInputsForTemplate before encoding");
2242
+ }
2243
+ const { params } = buildLaunchpadInitParams(opts, resolved.launchpad);
2244
+ return {
2245
+ initData: buildInitData2(params),
2246
+ asset: resolved.launchpad.asset,
2247
+ assetAmount: params.assetIn,
2248
+ maxDrawdownBps: resolved.launchpad.maxDrawdownBps
2249
+ };
2250
+ }
2251
+ if (templateKey === "morpho-supply") {
2252
+ const plan = resolved?.morphoSupply;
2253
+ if (!plan) throw new Error("morpho-supply: missing resolved market plan \u2014 resolve chain inputs before encoding");
2254
+ return {
2255
+ initData: buildInitData11(plan.morpho, plan.marketParams, plan.supplyAmount),
2256
+ asset: plan.asset,
2257
+ assetAmount: plan.supplyAmount
2258
+ };
2259
+ }
2260
+ if (templateKey === "concentrated-liquidity") {
2261
+ const plan = resolved?.concentratedLiquidity;
2262
+ if (!plan) throw new Error("concentrated-liquidity: missing resolved pool/market plan \u2014 resolve chain inputs before encoding");
2263
+ return {
2264
+ initData: buildInitData12(plan.params),
2265
+ asset: plan.asset,
2266
+ assetAmount: plan.params.collateralAmount
2267
+ };
2268
+ }
1374
2269
  throw new Error(`No init builder for template: ${templateKey}`);
1375
2270
  }
1376
2271
  function buildCallsForTemplate(templateKey, clone, asset, assetAmount, extraApprovals) {
1377
2272
  if (templateKey === "moonwell-supply") {
1378
2273
  return {
1379
- executeCalls: buildExecuteCalls(clone, asset, assetAmount),
1380
- settleCalls: buildSettleCalls(clone)
2274
+ executeCalls: buildExecuteCalls3(clone, asset, assetAmount),
2275
+ settleCalls: buildSettleCalls3(clone)
1381
2276
  };
1382
2277
  }
1383
2278
  if (templateKey === "venice-inference") {
1384
2279
  return {
1385
- executeCalls: buildExecuteCalls2(clone, asset, assetAmount),
1386
- settleCalls: buildSettleCalls2(clone)
2280
+ executeCalls: buildExecuteCalls4(clone, asset, assetAmount),
2281
+ settleCalls: buildSettleCalls4(clone)
1387
2282
  };
1388
2283
  }
1389
2284
  if (templateKey === "aerodrome-lp") {
1390
2285
  const tokenB = extraApprovals?.[0]?.token ?? ZERO;
1391
2286
  const amountB = extraApprovals?.[0]?.amount ?? 0n;
1392
2287
  return {
1393
- executeCalls: buildExecuteCalls3(clone, asset, assetAmount, tokenB, amountB),
1394
- settleCalls: buildSettleCalls3(clone)
2288
+ executeCalls: buildExecuteCalls5(clone, asset, assetAmount, tokenB, amountB),
2289
+ settleCalls: buildSettleCalls5(clone)
1395
2290
  };
1396
2291
  }
1397
2292
  if (templateKey === "wsteth-moonwell") {
1398
2293
  return {
1399
- executeCalls: buildExecuteCalls4(clone, asset, assetAmount),
1400
- settleCalls: buildSettleCalls4(clone)
2294
+ executeCalls: buildExecuteCalls6(clone, asset, assetAmount),
2295
+ settleCalls: buildSettleCalls6(clone)
1401
2296
  };
1402
2297
  }
1403
2298
  if (templateKey === "mamo-yield") {
1404
2299
  return {
1405
- executeCalls: buildExecuteCalls5(clone, asset, assetAmount),
1406
- settleCalls: buildSettleCalls5(clone)
2300
+ executeCalls: buildExecuteCalls7(clone, asset, assetAmount),
2301
+ settleCalls: buildSettleCalls7(clone)
1407
2302
  };
1408
2303
  }
1409
2304
  if (templateKey === "portfolio") {
1410
2305
  return {
1411
- executeCalls: buildExecuteCalls6(clone, asset, assetAmount),
1412
- settleCalls: buildSettleCalls6(clone)
2306
+ executeCalls: buildExecuteCalls8(clone, asset, assetAmount),
2307
+ settleCalls: buildSettleCalls8(clone)
1413
2308
  };
1414
2309
  }
1415
2310
  if (templateKey === "hyperliquid-perp") {
1416
2311
  return {
1417
- executeCalls: buildExecuteCalls7(clone, asset, assetAmount),
1418
- settleCalls: buildSettleCalls7(clone)
2312
+ executeCalls: buildExecuteCalls9(clone, asset, assetAmount),
2313
+ settleCalls: buildSettleCalls9(clone)
1419
2314
  };
1420
2315
  }
1421
2316
  if (templateKey === "hyperliquid-grid") {
1422
2317
  return {
1423
- executeCalls: buildExecuteCalls8(clone, asset, assetAmount),
1424
- settleCalls: buildSettleCalls8(clone)
2318
+ executeCalls: buildExecuteCalls10(clone, asset, assetAmount),
2319
+ settleCalls: buildSettleCalls10(clone)
2320
+ };
2321
+ }
2322
+ if (templateKey === "lighter-perp") {
2323
+ return {
2324
+ executeCalls: buildExecuteCalls(clone, asset, assetAmount),
2325
+ settleCalls: buildSettleCalls(clone)
2326
+ };
2327
+ }
2328
+ if (templateKey === "launchpad") {
2329
+ return {
2330
+ executeCalls: buildExecuteCalls2(clone, asset, assetAmount),
2331
+ settleCalls: buildSettleCalls2(clone)
2332
+ };
2333
+ }
2334
+ if (templateKey === "morpho-supply") {
2335
+ return {
2336
+ executeCalls: buildExecuteCalls11(clone, asset, assetAmount),
2337
+ settleCalls: buildSettleCalls11(clone)
2338
+ };
2339
+ }
2340
+ if (templateKey === "concentrated-liquidity") {
2341
+ return {
2342
+ executeCalls: buildExecuteCalls12(clone, asset, assetAmount),
2343
+ settleCalls: buildSettleCalls12(clone)
1425
2344
  };
1426
2345
  }
1427
2346
  throw new Error(`No call builder for template: ${templateKey}`);
@@ -1438,7 +2357,7 @@ function resolveSwapAdapter() {
1438
2357
  process.exit(1);
1439
2358
  }
1440
2359
  function resolveToken(symbolOrAddress) {
1441
- if (isAddress(symbolOrAddress)) return symbolOrAddress;
2360
+ if (isAddress2(symbolOrAddress)) return symbolOrAddress;
1442
2361
  const upper = symbolOrAddress.toUpperCase();
1443
2362
  const tokenMap = {
1444
2363
  ...TOKENS(),
@@ -1545,7 +2464,7 @@ async function selectBestFeeTier(params, deps = {}) {
1545
2464
  }
1546
2465
  async function getQuote(params, deps = {}) {
1547
2466
  const client = deps.client ?? getPublicClient();
1548
- const calldata = encodeFunctionData9({
2467
+ const calldata = encodeFunctionData11({
1549
2468
  abi: UNISWAP_QUOTER_V2_ABI,
1550
2469
  functionName: "quoteExactInputSingle",
1551
2470
  args: [
@@ -1571,7 +2490,7 @@ async function getQuote(params, deps = {}) {
1571
2490
  }
1572
2491
  async function getMultiHopQuote(params, deps = {}) {
1573
2492
  const client = deps.client ?? getPublicClient();
1574
- const calldata = encodeFunctionData9({
2493
+ const calldata = encodeFunctionData11({
1575
2494
  abi: UNISWAP_QUOTER_V2_ABI,
1576
2495
  functionName: "quoteExactInput",
1577
2496
  args: [params.path, params.amountIn]
@@ -1599,6 +2518,24 @@ function encodeSwapPath(tokens, fees) {
1599
2518
 
1600
2519
  export {
1601
2520
  HYPERLIQUID_PERP_STRATEGY_ABI,
2521
+ v3SingleHopExtraData,
2522
+ ZERO_ADDRESS,
2523
+ MORPHO_CL_VENUES,
2524
+ MORPHO_READ_ABI,
2525
+ VAULT_ASSET_ABI,
2526
+ ERC4626_PREVIEW_ABI,
2527
+ readTierRegistry,
2528
+ readAllowed,
2529
+ sameAddress,
2530
+ parseAddressFlag,
2531
+ parseBytes32Flag,
2532
+ parseIntFlag,
2533
+ parseUintFlag,
2534
+ planMorphoSupply,
2535
+ CL_DEFAULTS,
2536
+ twapTickFromCumulatives,
2537
+ planConcentratedLiquidity,
2538
+ parseSwapRouteSpec,
1602
2539
  computeProposalAssetChecks,
1603
2540
  parseAlignedOverrides,
1604
2541
  buildInitDataForTemplate,
@@ -1614,4 +2551,4 @@ export {
1614
2551
  applySlippage,
1615
2552
  encodeSwapPath
1616
2553
  };
1617
- //# sourceMappingURL=chunk-QFGZQYZA.js.map
2554
+ //# sourceMappingURL=chunk-WDPA2BYK.js.map