@sherwoodagent/cli 0.73.3 → 0.74.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.
- package/dist/{abis-KP7M4IPM.js → abis-D7EDCKVZ.js} +2 -2
- package/dist/{addresses-DGB3D457.js → addresses-OFFTM6NG.js} +4 -4
- package/dist/{agent-UNSW5IPO.js → agent-IJOOONON.js} +8 -8
- package/dist/{chat-KT2WVDT2.js → chat-3PM3GP3C.js} +9 -10
- package/dist/{chat-KT2WVDT2.js.map → chat-3PM3GP3C.js.map} +1 -1
- package/dist/{chunk-ROKE6ZAW.js → chunk-2OHX3O55.js} +6 -20
- package/dist/chunk-2OHX3O55.js.map +1 -0
- package/dist/{chunk-GSC7PVEO.js → chunk-6MV4ESXM.js} +43 -7
- package/dist/chunk-6MV4ESXM.js.map +1 -0
- package/dist/chunk-7BMCLMSE.js +173 -0
- package/dist/chunk-7BMCLMSE.js.map +1 -0
- package/dist/{chunk-NPWYX6NU.js → chunk-BD4ZV7FQ.js} +3 -3
- package/dist/{chunk-BKJ7HYX7.js → chunk-DGLLSZ2D.js} +10 -10
- package/dist/chunk-DGLLSZ2D.js.map +1 -0
- package/dist/chunk-EGJESQXZ.js +1 -0
- package/dist/chunk-I2PC6TBZ.js +3887 -0
- package/dist/chunk-I2PC6TBZ.js.map +1 -0
- package/dist/{chunk-CHWBQJLT.js → chunk-JF7KAVOM.js} +8 -21
- package/dist/chunk-JF7KAVOM.js.map +1 -0
- package/dist/{chunk-DXJJMRBM.js → chunk-LHVSS27T.js} +2 -2
- package/dist/{chunk-2U4TWPWQ.js → chunk-MUINMYCE.js} +5 -5
- package/dist/{chunk-GU5VZGXB.js → chunk-N3NVFSDQ.js} +5 -5
- package/dist/{chunk-CZRJ5GWE.js → chunk-RAP6MUMB.js} +54 -24
- package/dist/chunk-RAP6MUMB.js.map +1 -0
- package/dist/{chunk-ZURDCYGU.js → chunk-RE3PPAXZ.js} +9 -5
- package/dist/chunk-RE3PPAXZ.js.map +1 -0
- package/dist/{chunk-IFL5SREW.js → chunk-UINMHN6S.js} +2 -2
- package/dist/chunk-WBQMGZ5X.js +1253 -0
- package/dist/chunk-WBQMGZ5X.js.map +1 -0
- package/dist/{client-NAL3HVLK.js → client-C3C6IXAH.js} +4 -4
- package/dist/{config-FAQO37S7.js → config-7HU4X7EK.js} +4 -4
- package/dist/{eas-QAH7XVLK.js → eas-G4TPLJ6S.js} +7 -7
- package/dist/{governor-S56M6BV6.js → governor-PYQQ7QRG.js} +7 -7
- package/dist/index.js +209 -1295
- package/dist/index.js.map +1 -1
- package/dist/{network-MKMX2NG6.js → network-WU2QC3L4.js} +3 -3
- package/dist/{price-HHDBMKIE.js → price-DGGB6W2G.js} +15 -37
- package/dist/price-DGGB6W2G.js.map +1 -0
- package/dist/providers-YOOQFBN2.js +31 -0
- package/dist/providers-YOOQFBN2.js.map +1 -0
- package/dist/{research-IJBOMYL3.js → research-KX3LCAOQ.js} +9 -9
- package/dist/{session-L67AVWBY.js → session-GUVSID3Z.js} +19 -174
- package/dist/session-GUVSID3Z.js.map +1 -0
- package/dist/{trade-LGFQEK3I.js → trade-WDPMFFYB.js} +277 -43
- package/dist/trade-WDPMFFYB.js.map +1 -0
- package/dist/{vault-XWFPGHRA.js → vault-WDRLJLJ6.js} +14 -9
- package/dist/{xmtp-6US7GH3Z.js → xmtp-Q4ZSQV2Q.js} +11 -15
- package/dist/xmtp-Q4ZSQV2Q.js.map +1 -0
- package/package.json +3 -2
- package/dist/chunk-BKJ7HYX7.js.map +0 -1
- package/dist/chunk-BQMOE4FJ.js +0 -1629
- package/dist/chunk-BQMOE4FJ.js.map +0 -1
- package/dist/chunk-CHWBQJLT.js.map +0 -1
- package/dist/chunk-CZRJ5GWE.js.map +0 -1
- package/dist/chunk-DIZEB2VV.js +0 -325
- package/dist/chunk-DIZEB2VV.js.map +0 -1
- package/dist/chunk-GSC7PVEO.js.map +0 -1
- package/dist/chunk-ROKE6ZAW.js.map +0 -1
- package/dist/chunk-ZURDCYGU.js.map +0 -1
- package/dist/price-HHDBMKIE.js.map +0 -1
- package/dist/research-4TBGYEVI.js +0 -14
- package/dist/session-L67AVWBY.js.map +0 -1
- package/dist/trade-LGFQEK3I.js.map +0 -1
- package/dist/xmtp-6US7GH3Z.js.map +0 -1
- /package/dist/{abis-KP7M4IPM.js.map → abis-D7EDCKVZ.js.map} +0 -0
- /package/dist/{addresses-DGB3D457.js.map → addresses-OFFTM6NG.js.map} +0 -0
- /package/dist/{agent-UNSW5IPO.js.map → agent-IJOOONON.js.map} +0 -0
- /package/dist/{chunk-NPWYX6NU.js.map → chunk-BD4ZV7FQ.js.map} +0 -0
- /package/dist/{client-NAL3HVLK.js.map → chunk-EGJESQXZ.js.map} +0 -0
- /package/dist/{chunk-DXJJMRBM.js.map → chunk-LHVSS27T.js.map} +0 -0
- /package/dist/{chunk-2U4TWPWQ.js.map → chunk-MUINMYCE.js.map} +0 -0
- /package/dist/{chunk-GU5VZGXB.js.map → chunk-N3NVFSDQ.js.map} +0 -0
- /package/dist/{chunk-IFL5SREW.js.map → chunk-UINMHN6S.js.map} +0 -0
- /package/dist/{config-FAQO37S7.js.map → client-C3C6IXAH.js.map} +0 -0
- /package/dist/{eas-QAH7XVLK.js.map → config-7HU4X7EK.js.map} +0 -0
- /package/dist/{governor-S56M6BV6.js.map → eas-G4TPLJ6S.js.map} +0 -0
- /package/dist/{network-MKMX2NG6.js.map → governor-PYQQ7QRG.js.map} +0 -0
- /package/dist/{research-4TBGYEVI.js.map → network-WU2QC3L4.js.map} +0 -0
- /package/dist/{research-IJBOMYL3.js.map → research-KX3LCAOQ.js.map} +0 -0
- /package/dist/{vault-XWFPGHRA.js.map → vault-WDRLJLJ6.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -9,19 +9,48 @@ import {
|
|
|
9
9
|
hlPlaceLimitOrder,
|
|
10
10
|
resolveHLCoin
|
|
11
11
|
} from "./chunk-DBOINZYU.js";
|
|
12
|
-
import
|
|
13
|
-
UniswapProvider,
|
|
14
|
-
applySlippage,
|
|
15
|
-
encodeSwapPath,
|
|
16
|
-
getMultiHopQuote,
|
|
17
|
-
getQuote
|
|
18
|
-
} from "./chunk-DIZEB2VV.js";
|
|
12
|
+
import "./chunk-EGJESQXZ.js";
|
|
19
13
|
import {
|
|
20
14
|
chatCompletion,
|
|
21
15
|
checkApiKeyValid,
|
|
22
16
|
listModels,
|
|
23
17
|
provisionApiKey
|
|
24
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-BD4ZV7FQ.js";
|
|
19
|
+
import {
|
|
20
|
+
approveDepositor,
|
|
21
|
+
deposit,
|
|
22
|
+
depositWithEthWrap,
|
|
23
|
+
getAgentAddresses,
|
|
24
|
+
getAgentFeeBps,
|
|
25
|
+
getAssetAddress,
|
|
26
|
+
getAssetDecimals,
|
|
27
|
+
getBalance,
|
|
28
|
+
getNetDeposited,
|
|
29
|
+
getShareBalance,
|
|
30
|
+
getVaultAddress,
|
|
31
|
+
getVaultInfo,
|
|
32
|
+
getVaultOwner,
|
|
33
|
+
isAgent,
|
|
34
|
+
preflightDeposit,
|
|
35
|
+
preflightRedeem,
|
|
36
|
+
redeem,
|
|
37
|
+
registerAgent,
|
|
38
|
+
removeDepositor,
|
|
39
|
+
setAgentFeeBps,
|
|
40
|
+
setVaultAddress
|
|
41
|
+
} from "./chunk-RAP6MUMB.js";
|
|
42
|
+
import "./chunk-7BMCLMSE.js";
|
|
43
|
+
import {
|
|
44
|
+
applySlippage,
|
|
45
|
+
assetDecimalsForSymbol,
|
|
46
|
+
buildCallsForTemplate,
|
|
47
|
+
buildInitDataForTemplate,
|
|
48
|
+
computeProposalAssetChecks,
|
|
49
|
+
encodeSwapPath,
|
|
50
|
+
getMultiHopQuote,
|
|
51
|
+
getQuote,
|
|
52
|
+
resolveToken
|
|
53
|
+
} from "./chunk-WBQMGZ5X.js";
|
|
25
54
|
import {
|
|
26
55
|
createApproval,
|
|
27
56
|
createJoinRequest,
|
|
@@ -32,42 +61,20 @@ import {
|
|
|
32
61
|
queryJoinRequests,
|
|
33
62
|
revokeJoinRequest,
|
|
34
63
|
stripReferrerPrefix
|
|
35
|
-
} from "./chunk-
|
|
64
|
+
} from "./chunk-N3NVFSDQ.js";
|
|
36
65
|
import {
|
|
37
66
|
createFund,
|
|
38
67
|
getActiveFunds,
|
|
39
68
|
getFund,
|
|
40
69
|
subdomainExists,
|
|
41
70
|
updateMetadata
|
|
42
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-MUINMYCE.js";
|
|
43
72
|
import {
|
|
44
73
|
resolveFund,
|
|
45
74
|
resolveVaultFund,
|
|
46
75
|
searchFundAcrossChains,
|
|
47
76
|
setTextRecord
|
|
48
|
-
} from "./chunk-
|
|
49
|
-
import {
|
|
50
|
-
approveDepositor,
|
|
51
|
-
deposit,
|
|
52
|
-
depositWithEthWrap,
|
|
53
|
-
executeBatch,
|
|
54
|
-
getAgentFeeBps,
|
|
55
|
-
getAssetAddress,
|
|
56
|
-
getAssetDecimals,
|
|
57
|
-
getBalance,
|
|
58
|
-
getShareBalance,
|
|
59
|
-
getVaultAddress,
|
|
60
|
-
getVaultInfo,
|
|
61
|
-
getVaultOwner,
|
|
62
|
-
isAgent,
|
|
63
|
-
preflightDeposit,
|
|
64
|
-
preflightRedeem,
|
|
65
|
-
redeem,
|
|
66
|
-
registerAgent,
|
|
67
|
-
removeDepositor,
|
|
68
|
-
setAgentFeeBps,
|
|
69
|
-
setVaultAddress
|
|
70
|
-
} from "./chunk-CZRJ5GWE.js";
|
|
77
|
+
} from "./chunk-JF7KAVOM.js";
|
|
71
78
|
import {
|
|
72
79
|
PROPOSAL_STATE,
|
|
73
80
|
PROPOSAL_STATES,
|
|
@@ -101,21 +108,17 @@ import {
|
|
|
101
108
|
setVotingPeriod,
|
|
102
109
|
settleProposal,
|
|
103
110
|
vote
|
|
104
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-RE3PPAXZ.js";
|
|
105
112
|
import {
|
|
106
113
|
AERODROME,
|
|
107
114
|
AGENT_REGISTRY,
|
|
108
|
-
CHAINLINK,
|
|
109
115
|
MOONWELL,
|
|
110
|
-
ROBINHOOD_STOCK_ROUTES,
|
|
111
116
|
SHERWOOD,
|
|
112
117
|
STRATEGY_TEMPLATES,
|
|
113
|
-
SYNTHRA,
|
|
114
118
|
TOKENS,
|
|
115
119
|
UNISWAP,
|
|
116
|
-
VENICE
|
|
117
|
-
|
|
118
|
-
} from "./chunk-IFL5SREW.js";
|
|
120
|
+
VENICE
|
|
121
|
+
} from "./chunk-UINMHN6S.js";
|
|
119
122
|
import {
|
|
120
123
|
GAS_UNITS,
|
|
121
124
|
estimateGasCushion,
|
|
@@ -126,7 +129,7 @@ import {
|
|
|
126
129
|
sendTxWithRetry,
|
|
127
130
|
waitForReceipt,
|
|
128
131
|
writeContractWithRetry
|
|
129
|
-
} from "./chunk-
|
|
132
|
+
} from "./chunk-2OHX3O55.js";
|
|
130
133
|
import {
|
|
131
134
|
DEFAULT_NETWORK,
|
|
132
135
|
VALID_NETWORKS,
|
|
@@ -138,7 +141,7 @@ import {
|
|
|
138
141
|
isTestnet,
|
|
139
142
|
setNetwork,
|
|
140
143
|
withNetwork
|
|
141
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-LHVSS27T.js";
|
|
142
145
|
import {
|
|
143
146
|
addFund,
|
|
144
147
|
cacheGroupId,
|
|
@@ -151,6 +154,7 @@ import {
|
|
|
151
154
|
getUniswapApiKey,
|
|
152
155
|
getVeniceApiKey,
|
|
153
156
|
loadConfig,
|
|
157
|
+
requirePrivateKey,
|
|
154
158
|
setAgentId,
|
|
155
159
|
setAnthropicApiKey,
|
|
156
160
|
setChainContract,
|
|
@@ -160,7 +164,7 @@ import {
|
|
|
160
164
|
setPrivateKey,
|
|
161
165
|
setUniswapApiKey,
|
|
162
166
|
setVeniceApiKey
|
|
163
|
-
} from "./chunk-
|
|
167
|
+
} from "./chunk-6MV4ESXM.js";
|
|
164
168
|
import {
|
|
165
169
|
BASE_STRATEGY_ABI,
|
|
166
170
|
ERC20_ABI,
|
|
@@ -170,7 +174,7 @@ import {
|
|
|
170
174
|
SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
|
|
171
175
|
SYNDICATE_VAULT_ABI,
|
|
172
176
|
VENICE_STAKING_ABI
|
|
173
|
-
} from "./chunk-
|
|
177
|
+
} from "./chunk-I2PC6TBZ.js";
|
|
174
178
|
import {
|
|
175
179
|
fetchMetadata,
|
|
176
180
|
mergeFundMetadata,
|
|
@@ -186,6 +190,9 @@ import chalk16 from "chalk";
|
|
|
186
190
|
import ora9 from "ora";
|
|
187
191
|
import { input, confirm, select } from "@inquirer/prompts";
|
|
188
192
|
|
|
193
|
+
// src/lib/generated/contract-constants.ts
|
|
194
|
+
var MAX_AGENT_FEE_BPS = 1500;
|
|
195
|
+
|
|
189
196
|
// src/lib/format.ts
|
|
190
197
|
function formatDurationShort(seconds) {
|
|
191
198
|
const s = Number(seconds);
|
|
@@ -216,42 +223,8 @@ function parseBigIntArg(value, name) {
|
|
|
216
223
|
return BigInt(value);
|
|
217
224
|
}
|
|
218
225
|
|
|
219
|
-
// src/providers/moonwell.ts
|
|
220
|
-
import { base, baseSepolia } from "viem/chains";
|
|
221
|
-
var MoonwellProvider = class {
|
|
222
|
-
info() {
|
|
223
|
-
return {
|
|
224
|
-
name: "moonwell",
|
|
225
|
-
type: "lending",
|
|
226
|
-
capabilities: [
|
|
227
|
-
"lend.deposit",
|
|
228
|
-
"lend.borrow",
|
|
229
|
-
"lend.repay",
|
|
230
|
-
"lend.withdraw",
|
|
231
|
-
"lend.positions"
|
|
232
|
-
],
|
|
233
|
-
supportedChains: [base, baseSepolia]
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
|
-
async depositCollateral(params) {
|
|
237
|
-
throw new Error("Not implemented \u2014 wire up viem client");
|
|
238
|
-
}
|
|
239
|
-
async borrow(params) {
|
|
240
|
-
throw new Error("Not implemented");
|
|
241
|
-
}
|
|
242
|
-
async repay(params) {
|
|
243
|
-
throw new Error("Not implemented");
|
|
244
|
-
}
|
|
245
|
-
async withdrawCollateral(params) {
|
|
246
|
-
throw new Error("Not implemented");
|
|
247
|
-
}
|
|
248
|
-
async getPosition(account) {
|
|
249
|
-
throw new Error("Not implemented");
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
|
|
253
226
|
// src/commands/strategy-template.ts
|
|
254
|
-
import { parseUnits, formatUnits as formatUnits2, isAddress as isAddress2, erc20Abi, encodeAbiParameters as
|
|
227
|
+
import { parseUnits, formatUnits as formatUnits2, isAddress as isAddress2, erc20Abi, encodeAbiParameters as encodeAbiParameters3, decodeAbiParameters } from "viem";
|
|
255
228
|
import chalk from "chalk";
|
|
256
229
|
import ora from "ora";
|
|
257
230
|
import { writeFileSync, mkdirSync } from "fs";
|
|
@@ -2077,603 +2050,8 @@ function encodeSetCommission(args, chainId) {
|
|
|
2077
2050
|
// ../sdk/dist/reads/funds.js
|
|
2078
2051
|
import { getAddress as getAddress8 } from "viem";
|
|
2079
2052
|
|
|
2080
|
-
// src/strategies/moonwell-supply-template.ts
|
|
2081
|
-
import { encodeAbiParameters as encodeAbiParameters3, encodeFunctionData as encodeFunctionData8 } from "viem";
|
|
2082
|
-
function buildInitData(underlying, mToken, supplyAmount, minRedeemAmount, isNativeEthMarket) {
|
|
2083
|
-
return encodeAbiParameters3(
|
|
2084
|
-
[
|
|
2085
|
-
{ type: "address" },
|
|
2086
|
-
{ type: "address" },
|
|
2087
|
-
{ type: "uint256" },
|
|
2088
|
-
{ type: "uint256" },
|
|
2089
|
-
{ type: "bool" }
|
|
2090
|
-
],
|
|
2091
|
-
[underlying, mToken, supplyAmount, minRedeemAmount, isNativeEthMarket]
|
|
2092
|
-
);
|
|
2093
|
-
}
|
|
2094
|
-
function buildExecuteCalls(clone, underlying, supplyAmount) {
|
|
2095
|
-
return [
|
|
2096
|
-
{
|
|
2097
|
-
target: underlying,
|
|
2098
|
-
data: encodeFunctionData8({
|
|
2099
|
-
abi: ERC20_ABI,
|
|
2100
|
-
functionName: "approve",
|
|
2101
|
-
args: [clone, supplyAmount]
|
|
2102
|
-
}),
|
|
2103
|
-
value: 0n
|
|
2104
|
-
},
|
|
2105
|
-
{
|
|
2106
|
-
target: clone,
|
|
2107
|
-
data: encodeFunctionData8({
|
|
2108
|
-
abi: BASE_STRATEGY_ABI,
|
|
2109
|
-
functionName: "execute"
|
|
2110
|
-
}),
|
|
2111
|
-
value: 0n
|
|
2112
|
-
}
|
|
2113
|
-
];
|
|
2114
|
-
}
|
|
2115
|
-
function buildSettleCalls(clone) {
|
|
2116
|
-
return [
|
|
2117
|
-
{
|
|
2118
|
-
target: clone,
|
|
2119
|
-
data: encodeFunctionData8({
|
|
2120
|
-
abi: BASE_STRATEGY_ABI,
|
|
2121
|
-
functionName: "settle"
|
|
2122
|
-
}),
|
|
2123
|
-
value: 0n
|
|
2124
|
-
}
|
|
2125
|
-
];
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
|
-
// src/strategies/venice-inference-template.ts
|
|
2129
|
-
import { encodeAbiParameters as encodeAbiParameters4, encodeFunctionData as encodeFunctionData9 } from "viem";
|
|
2130
|
-
var INIT_PARAMS_TYPES = [
|
|
2131
|
-
{
|
|
2132
|
-
type: "tuple",
|
|
2133
|
-
components: [
|
|
2134
|
-
{ name: "asset", type: "address" },
|
|
2135
|
-
{ name: "weth", type: "address" },
|
|
2136
|
-
{ name: "vvv", type: "address" },
|
|
2137
|
-
{ name: "sVVV", type: "address" },
|
|
2138
|
-
{ name: "aeroRouter", type: "address" },
|
|
2139
|
-
{ name: "aeroFactory", type: "address" },
|
|
2140
|
-
{ name: "agent", type: "address" },
|
|
2141
|
-
{ name: "assetAmount", type: "uint256" },
|
|
2142
|
-
{ name: "minVVV", type: "uint256" },
|
|
2143
|
-
{ name: "deadlineOffset", type: "uint256" },
|
|
2144
|
-
{ name: "singleHop", type: "bool" }
|
|
2145
|
-
]
|
|
2146
|
-
}
|
|
2147
|
-
];
|
|
2148
|
-
function buildInitData2(params) {
|
|
2149
|
-
return encodeAbiParameters4(INIT_PARAMS_TYPES, [params]);
|
|
2150
|
-
}
|
|
2151
|
-
function buildExecuteCalls2(clone, asset, assetAmount) {
|
|
2152
|
-
return [
|
|
2153
|
-
{
|
|
2154
|
-
target: asset,
|
|
2155
|
-
data: encodeFunctionData9({
|
|
2156
|
-
abi: ERC20_ABI,
|
|
2157
|
-
functionName: "approve",
|
|
2158
|
-
args: [clone, assetAmount]
|
|
2159
|
-
}),
|
|
2160
|
-
value: 0n
|
|
2161
|
-
},
|
|
2162
|
-
{
|
|
2163
|
-
target: clone,
|
|
2164
|
-
data: encodeFunctionData9({
|
|
2165
|
-
abi: BASE_STRATEGY_ABI,
|
|
2166
|
-
functionName: "execute"
|
|
2167
|
-
}),
|
|
2168
|
-
value: 0n
|
|
2169
|
-
}
|
|
2170
|
-
];
|
|
2171
|
-
}
|
|
2172
|
-
function buildSettleCalls2(clone) {
|
|
2173
|
-
return [
|
|
2174
|
-
{
|
|
2175
|
-
target: clone,
|
|
2176
|
-
data: encodeFunctionData9({
|
|
2177
|
-
abi: BASE_STRATEGY_ABI,
|
|
2178
|
-
functionName: "settle"
|
|
2179
|
-
}),
|
|
2180
|
-
value: 0n
|
|
2181
|
-
}
|
|
2182
|
-
];
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
// src/strategies/aerodrome-lp-template.ts
|
|
2186
|
-
import { encodeAbiParameters as encodeAbiParameters5, encodeFunctionData as encodeFunctionData10 } from "viem";
|
|
2187
|
-
var INIT_PARAMS_TYPES2 = [
|
|
2188
|
-
{
|
|
2189
|
-
type: "tuple",
|
|
2190
|
-
components: [
|
|
2191
|
-
{ name: "tokenA", type: "address" },
|
|
2192
|
-
{ name: "tokenB", type: "address" },
|
|
2193
|
-
{ name: "stable", type: "bool" },
|
|
2194
|
-
{ name: "factory", type: "address" },
|
|
2195
|
-
{ name: "router", type: "address" },
|
|
2196
|
-
{ name: "gauge", type: "address" },
|
|
2197
|
-
{ name: "lpToken", type: "address" },
|
|
2198
|
-
{ name: "amountADesired", type: "uint256" },
|
|
2199
|
-
{ name: "amountBDesired", type: "uint256" },
|
|
2200
|
-
{ name: "amountAMin", type: "uint256" },
|
|
2201
|
-
{ name: "amountBMin", type: "uint256" },
|
|
2202
|
-
{ name: "minAmountAOut", type: "uint256" },
|
|
2203
|
-
{ name: "minAmountBOut", type: "uint256" }
|
|
2204
|
-
]
|
|
2205
|
-
}
|
|
2206
|
-
];
|
|
2207
|
-
function buildInitData3(params) {
|
|
2208
|
-
return encodeAbiParameters5(INIT_PARAMS_TYPES2, [params]);
|
|
2209
|
-
}
|
|
2210
|
-
function buildExecuteCalls3(clone, tokenA, amountA, tokenB, amountB) {
|
|
2211
|
-
return [
|
|
2212
|
-
{
|
|
2213
|
-
target: tokenA,
|
|
2214
|
-
data: encodeFunctionData10({
|
|
2215
|
-
abi: ERC20_ABI,
|
|
2216
|
-
functionName: "approve",
|
|
2217
|
-
args: [clone, amountA]
|
|
2218
|
-
}),
|
|
2219
|
-
value: 0n
|
|
2220
|
-
},
|
|
2221
|
-
{
|
|
2222
|
-
target: tokenB,
|
|
2223
|
-
data: encodeFunctionData10({
|
|
2224
|
-
abi: ERC20_ABI,
|
|
2225
|
-
functionName: "approve",
|
|
2226
|
-
args: [clone, amountB]
|
|
2227
|
-
}),
|
|
2228
|
-
value: 0n
|
|
2229
|
-
},
|
|
2230
|
-
{
|
|
2231
|
-
target: clone,
|
|
2232
|
-
data: encodeFunctionData10({
|
|
2233
|
-
abi: BASE_STRATEGY_ABI,
|
|
2234
|
-
functionName: "execute"
|
|
2235
|
-
}),
|
|
2236
|
-
value: 0n
|
|
2237
|
-
}
|
|
2238
|
-
];
|
|
2239
|
-
}
|
|
2240
|
-
function buildSettleCalls3(clone) {
|
|
2241
|
-
return [
|
|
2242
|
-
{
|
|
2243
|
-
target: clone,
|
|
2244
|
-
data: encodeFunctionData10({
|
|
2245
|
-
abi: BASE_STRATEGY_ABI,
|
|
2246
|
-
functionName: "settle"
|
|
2247
|
-
}),
|
|
2248
|
-
value: 0n
|
|
2249
|
-
}
|
|
2250
|
-
];
|
|
2251
|
-
}
|
|
2252
|
-
|
|
2253
|
-
// src/strategies/wsteth-moonwell-template.ts
|
|
2254
|
-
import { encodeAbiParameters as encodeAbiParameters6, encodeFunctionData as encodeFunctionData11, maxUint256 as maxUint2562 } from "viem";
|
|
2255
|
-
var INIT_PARAMS_TYPES3 = [
|
|
2256
|
-
{
|
|
2257
|
-
type: "tuple",
|
|
2258
|
-
components: [
|
|
2259
|
-
{ name: "weth", type: "address" },
|
|
2260
|
-
{ name: "wsteth", type: "address" },
|
|
2261
|
-
{ name: "mwsteth", type: "address" },
|
|
2262
|
-
{ name: "aeroRouter", type: "address" },
|
|
2263
|
-
{ name: "aeroFactory", type: "address" },
|
|
2264
|
-
{ name: "chainlinkWstethEthFeed", type: "address" },
|
|
2265
|
-
{ name: "supplyAmount", type: "uint256" },
|
|
2266
|
-
{ name: "minWstethOutPerWeth", type: "uint256" },
|
|
2267
|
-
{ name: "minWethOutPerWsteth", type: "uint256" },
|
|
2268
|
-
{ name: "deadlineOffset", type: "uint256" }
|
|
2269
|
-
]
|
|
2270
|
-
}
|
|
2271
|
-
];
|
|
2272
|
-
function buildInitData4(params) {
|
|
2273
|
-
return encodeAbiParameters6(INIT_PARAMS_TYPES3, [params]);
|
|
2274
|
-
}
|
|
2275
|
-
function buildExecuteCalls4(clone, weth, supplyAmount) {
|
|
2276
|
-
const approveAmount = supplyAmount === 0n ? maxUint2562 : supplyAmount;
|
|
2277
|
-
return [
|
|
2278
|
-
{
|
|
2279
|
-
target: weth,
|
|
2280
|
-
data: encodeFunctionData11({
|
|
2281
|
-
abi: ERC20_ABI,
|
|
2282
|
-
functionName: "approve",
|
|
2283
|
-
args: [clone, approveAmount]
|
|
2284
|
-
}),
|
|
2285
|
-
value: 0n
|
|
2286
|
-
},
|
|
2287
|
-
{
|
|
2288
|
-
target: clone,
|
|
2289
|
-
data: encodeFunctionData11({
|
|
2290
|
-
abi: BASE_STRATEGY_ABI,
|
|
2291
|
-
functionName: "execute"
|
|
2292
|
-
}),
|
|
2293
|
-
value: 0n
|
|
2294
|
-
},
|
|
2295
|
-
{
|
|
2296
|
-
target: weth,
|
|
2297
|
-
data: encodeFunctionData11({
|
|
2298
|
-
abi: ERC20_ABI,
|
|
2299
|
-
functionName: "approve",
|
|
2300
|
-
args: [clone, 0n]
|
|
2301
|
-
}),
|
|
2302
|
-
value: 0n
|
|
2303
|
-
}
|
|
2304
|
-
];
|
|
2305
|
-
}
|
|
2306
|
-
function buildSettleCalls4(clone) {
|
|
2307
|
-
return [
|
|
2308
|
-
{
|
|
2309
|
-
target: clone,
|
|
2310
|
-
data: encodeFunctionData11({
|
|
2311
|
-
abi: BASE_STRATEGY_ABI,
|
|
2312
|
-
functionName: "settle"
|
|
2313
|
-
}),
|
|
2314
|
-
value: 0n
|
|
2315
|
-
}
|
|
2316
|
-
];
|
|
2317
|
-
}
|
|
2318
|
-
|
|
2319
|
-
// src/strategies/mamo-yield-template.ts
|
|
2320
|
-
import { encodeAbiParameters as encodeAbiParameters7, encodeFunctionData as encodeFunctionData12 } from "viem";
|
|
2321
|
-
function buildInitData5(underlying, mamoFactory, minRedeemAmount) {
|
|
2322
|
-
return encodeAbiParameters7(
|
|
2323
|
-
[
|
|
2324
|
-
{ type: "address" },
|
|
2325
|
-
{ type: "address" },
|
|
2326
|
-
{ type: "uint256" }
|
|
2327
|
-
],
|
|
2328
|
-
[underlying, mamoFactory, minRedeemAmount]
|
|
2329
|
-
);
|
|
2330
|
-
}
|
|
2331
|
-
function buildExecuteCalls5(clone, underlying, amount) {
|
|
2332
|
-
return [
|
|
2333
|
-
{
|
|
2334
|
-
target: underlying,
|
|
2335
|
-
data: encodeFunctionData12({
|
|
2336
|
-
abi: ERC20_ABI,
|
|
2337
|
-
functionName: "approve",
|
|
2338
|
-
args: [clone, amount]
|
|
2339
|
-
}),
|
|
2340
|
-
value: 0n
|
|
2341
|
-
},
|
|
2342
|
-
{
|
|
2343
|
-
target: clone,
|
|
2344
|
-
data: encodeFunctionData12({
|
|
2345
|
-
abi: BASE_STRATEGY_ABI,
|
|
2346
|
-
functionName: "execute"
|
|
2347
|
-
}),
|
|
2348
|
-
value: 0n
|
|
2349
|
-
}
|
|
2350
|
-
];
|
|
2351
|
-
}
|
|
2352
|
-
function buildSettleCalls5(clone) {
|
|
2353
|
-
return [
|
|
2354
|
-
{
|
|
2355
|
-
target: clone,
|
|
2356
|
-
data: encodeFunctionData12({
|
|
2357
|
-
abi: BASE_STRATEGY_ABI,
|
|
2358
|
-
functionName: "settle"
|
|
2359
|
-
}),
|
|
2360
|
-
value: 0n
|
|
2361
|
-
}
|
|
2362
|
-
];
|
|
2363
|
-
}
|
|
2364
|
-
|
|
2365
|
-
// src/strategies/portfolio-template.ts
|
|
2366
|
-
import { concat as concat2, encodeAbiParameters as encodeAbiParameters8, encodeFunctionData as encodeFunctionData13, numberToHex, pad } from "viem";
|
|
2367
|
-
function withMode(mode, routeData) {
|
|
2368
|
-
const modeByte = `0x${mode.toString(16).padStart(2, "0")}`;
|
|
2369
|
-
return concat2([modeByte, routeData]);
|
|
2370
|
-
}
|
|
2371
|
-
function v3SingleHopExtraData(fee) {
|
|
2372
|
-
return withMode(0, encodeAbiParameters8([{ type: "uint24" }], [fee]));
|
|
2373
|
-
}
|
|
2374
|
-
function v4SingleHopExtraData(fee, tickSpacing) {
|
|
2375
|
-
return withMode(
|
|
2376
|
-
2,
|
|
2377
|
-
encodeAbiParameters8(
|
|
2378
|
-
[{ type: "uint24" }, { type: "int24" }],
|
|
2379
|
-
[fee, tickSpacing]
|
|
2380
|
-
)
|
|
2381
|
-
);
|
|
2382
|
-
}
|
|
2383
|
-
function v4PathExtraData(hops) {
|
|
2384
|
-
if (hops.length < 2) throw new Error("v4PathExtraData: mode 3 needs >= 2 hops (use v4SingleHopExtraData for one)");
|
|
2385
|
-
return withMode(
|
|
2386
|
-
3,
|
|
2387
|
-
encodeAbiParameters8(
|
|
2388
|
-
[
|
|
2389
|
-
{
|
|
2390
|
-
type: "tuple[]",
|
|
2391
|
-
components: [
|
|
2392
|
-
{ type: "address", name: "currency" },
|
|
2393
|
-
{ type: "uint24", name: "fee" },
|
|
2394
|
-
{ type: "int24", name: "tickSpacing" }
|
|
2395
|
-
]
|
|
2396
|
-
}
|
|
2397
|
-
],
|
|
2398
|
-
[hops.map((h) => ({ currency: h.currency, fee: h.fee, tickSpacing: h.tickSpacing }))]
|
|
2399
|
-
)
|
|
2400
|
-
);
|
|
2401
|
-
}
|
|
2402
|
-
var EQUITY_MAX_PRICE_AGE_SECONDS = 96 * 60 * 60;
|
|
2403
|
-
var MIN_MAX_PRICE_AGE = 3600;
|
|
2404
|
-
var MAX_MAX_PRICE_AGE = 2592e3;
|
|
2405
|
-
function pushFeedId(feed, maxAgeSeconds) {
|
|
2406
|
-
if (maxAgeSeconds === void 0 || maxAgeSeconds === 0) {
|
|
2407
|
-
return pad(feed, { size: 32 });
|
|
2408
|
-
}
|
|
2409
|
-
if (!Number.isInteger(maxAgeSeconds) || maxAgeSeconds < MIN_MAX_PRICE_AGE || maxAgeSeconds > MAX_MAX_PRICE_AGE) {
|
|
2410
|
-
throw new Error(
|
|
2411
|
-
`pushFeedId: maxAgeSeconds must be an integer in [${MIN_MAX_PRICE_AGE}, ${MAX_MAX_PRICE_AGE}] (or 0 for the contract default), got ${maxAgeSeconds}`
|
|
2412
|
-
);
|
|
2413
|
-
}
|
|
2414
|
-
const packed = BigInt(maxAgeSeconds) << 160n | BigInt(feed);
|
|
2415
|
-
return numberToHex(packed, { size: 32 });
|
|
2416
|
-
}
|
|
2417
|
-
function buildInitData6(asset, swapAdapter, chainlinkVerifier, allocations, totalAmount, maxSlippageBps) {
|
|
2418
|
-
const tokens = allocations.map((a) => a.token);
|
|
2419
|
-
const weightsBps = allocations.map((a) => BigInt(a.weightBps));
|
|
2420
|
-
const swapExtraData = allocations.map((a) => a.swapExtraData);
|
|
2421
|
-
const priceDecimals = allocations.map((a) => a.priceDecimals);
|
|
2422
|
-
const feedIds = allocations.map((a) => a.feedId);
|
|
2423
|
-
return encodeAbiParameters8(
|
|
2424
|
-
[
|
|
2425
|
-
{ type: "address" },
|
|
2426
|
-
{ type: "address" },
|
|
2427
|
-
{ type: "address" },
|
|
2428
|
-
{ type: "address[]" },
|
|
2429
|
-
{ type: "uint256[]" },
|
|
2430
|
-
{ type: "uint256" },
|
|
2431
|
-
{ type: "uint256" },
|
|
2432
|
-
{ type: "bytes[]" },
|
|
2433
|
-
{ type: "uint8[]" },
|
|
2434
|
-
{ type: "bytes32[]" }
|
|
2435
|
-
],
|
|
2436
|
-
[
|
|
2437
|
-
asset,
|
|
2438
|
-
swapAdapter,
|
|
2439
|
-
chainlinkVerifier,
|
|
2440
|
-
tokens,
|
|
2441
|
-
weightsBps,
|
|
2442
|
-
totalAmount,
|
|
2443
|
-
BigInt(maxSlippageBps),
|
|
2444
|
-
swapExtraData,
|
|
2445
|
-
priceDecimals,
|
|
2446
|
-
feedIds
|
|
2447
|
-
]
|
|
2448
|
-
);
|
|
2449
|
-
}
|
|
2450
|
-
function buildExecuteCalls6(clone, asset, totalAmount) {
|
|
2451
|
-
return [
|
|
2452
|
-
{
|
|
2453
|
-
target: asset,
|
|
2454
|
-
data: encodeFunctionData13({
|
|
2455
|
-
abi: ERC20_ABI,
|
|
2456
|
-
functionName: "approve",
|
|
2457
|
-
args: [clone, totalAmount]
|
|
2458
|
-
}),
|
|
2459
|
-
value: 0n
|
|
2460
|
-
},
|
|
2461
|
-
{
|
|
2462
|
-
target: clone,
|
|
2463
|
-
data: encodeFunctionData13({
|
|
2464
|
-
abi: BASE_STRATEGY_ABI,
|
|
2465
|
-
functionName: "execute"
|
|
2466
|
-
}),
|
|
2467
|
-
value: 0n
|
|
2468
|
-
}
|
|
2469
|
-
];
|
|
2470
|
-
}
|
|
2471
|
-
function buildSettleCalls6(clone) {
|
|
2472
|
-
return [
|
|
2473
|
-
{
|
|
2474
|
-
target: clone,
|
|
2475
|
-
data: encodeFunctionData13({
|
|
2476
|
-
abi: BASE_STRATEGY_ABI,
|
|
2477
|
-
functionName: "settle"
|
|
2478
|
-
}),
|
|
2479
|
-
value: 0n
|
|
2480
|
-
}
|
|
2481
|
-
];
|
|
2482
|
-
}
|
|
2483
|
-
|
|
2484
|
-
// src/strategies/hyperliquid-perp-template.ts
|
|
2485
|
-
import { encodeAbiParameters as encodeAbiParameters9, encodeFunctionData as encodeFunctionData14, maxUint256 as maxUint2563 } from "viem";
|
|
2486
|
-
function buildInitData7(asset, depositAmount, perpAssetIndex, leverage, maxPositionSize, maxTradesPerDay) {
|
|
2487
|
-
return encodeAbiParameters9(
|
|
2488
|
-
[
|
|
2489
|
-
{ type: "address" },
|
|
2490
|
-
{ type: "uint256" },
|
|
2491
|
-
{ type: "uint32" },
|
|
2492
|
-
{ type: "uint32" },
|
|
2493
|
-
{ type: "uint256" },
|
|
2494
|
-
{ type: "uint32" }
|
|
2495
|
-
],
|
|
2496
|
-
[asset, depositAmount, perpAssetIndex, leverage, maxPositionSize, maxTradesPerDay]
|
|
2497
|
-
);
|
|
2498
|
-
}
|
|
2499
|
-
function buildExecuteCalls7(clone, asset, amount) {
|
|
2500
|
-
const approveAmount = amount === 0n ? maxUint2563 : amount;
|
|
2501
|
-
return [
|
|
2502
|
-
{
|
|
2503
|
-
target: asset,
|
|
2504
|
-
data: encodeFunctionData14({
|
|
2505
|
-
abi: ERC20_ABI,
|
|
2506
|
-
functionName: "approve",
|
|
2507
|
-
args: [clone, approveAmount]
|
|
2508
|
-
}),
|
|
2509
|
-
value: 0n
|
|
2510
|
-
},
|
|
2511
|
-
{
|
|
2512
|
-
target: clone,
|
|
2513
|
-
data: encodeFunctionData14({
|
|
2514
|
-
abi: BASE_STRATEGY_ABI,
|
|
2515
|
-
functionName: "execute"
|
|
2516
|
-
}),
|
|
2517
|
-
value: 0n
|
|
2518
|
-
},
|
|
2519
|
-
{
|
|
2520
|
-
target: asset,
|
|
2521
|
-
data: encodeFunctionData14({
|
|
2522
|
-
abi: ERC20_ABI,
|
|
2523
|
-
functionName: "approve",
|
|
2524
|
-
args: [clone, 0n]
|
|
2525
|
-
}),
|
|
2526
|
-
value: 0n
|
|
2527
|
-
}
|
|
2528
|
-
];
|
|
2529
|
-
}
|
|
2530
|
-
function buildSettleCalls7(clone) {
|
|
2531
|
-
return [
|
|
2532
|
-
{
|
|
2533
|
-
target: clone,
|
|
2534
|
-
data: encodeFunctionData14({
|
|
2535
|
-
abi: BASE_STRATEGY_ABI,
|
|
2536
|
-
functionName: "settle"
|
|
2537
|
-
}),
|
|
2538
|
-
value: 0n
|
|
2539
|
-
}
|
|
2540
|
-
];
|
|
2541
|
-
}
|
|
2542
|
-
|
|
2543
|
-
// src/strategies/hyperliquid-grid-template.ts
|
|
2544
|
-
import { encodeAbiParameters as encodeAbiParameters10, encodeFunctionData as encodeFunctionData15, maxUint256 as maxUint2564 } from "viem";
|
|
2545
|
-
function buildInitData8(asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices) {
|
|
2546
|
-
return encodeAbiParameters10(
|
|
2547
|
-
[
|
|
2548
|
-
{ type: "address" },
|
|
2549
|
-
{ type: "uint256" },
|
|
2550
|
-
{ type: "uint32" },
|
|
2551
|
-
{ type: "uint256" },
|
|
2552
|
-
{ type: "uint32" },
|
|
2553
|
-
{ type: "uint32[]" }
|
|
2554
|
-
],
|
|
2555
|
-
[asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices]
|
|
2556
|
-
);
|
|
2557
|
-
}
|
|
2558
|
-
function buildExecuteCalls8(clone, asset, amount) {
|
|
2559
|
-
const approveAmount = amount === 0n ? maxUint2564 : amount;
|
|
2560
|
-
return [
|
|
2561
|
-
{
|
|
2562
|
-
target: asset,
|
|
2563
|
-
data: encodeFunctionData15({
|
|
2564
|
-
abi: ERC20_ABI,
|
|
2565
|
-
functionName: "approve",
|
|
2566
|
-
args: [clone, approveAmount]
|
|
2567
|
-
}),
|
|
2568
|
-
value: 0n
|
|
2569
|
-
},
|
|
2570
|
-
{
|
|
2571
|
-
target: clone,
|
|
2572
|
-
data: encodeFunctionData15({
|
|
2573
|
-
abi: BASE_STRATEGY_ABI,
|
|
2574
|
-
functionName: "execute"
|
|
2575
|
-
}),
|
|
2576
|
-
value: 0n
|
|
2577
|
-
},
|
|
2578
|
-
{
|
|
2579
|
-
target: asset,
|
|
2580
|
-
data: encodeFunctionData15({
|
|
2581
|
-
abi: ERC20_ABI,
|
|
2582
|
-
functionName: "approve",
|
|
2583
|
-
args: [clone, 0n]
|
|
2584
|
-
}),
|
|
2585
|
-
value: 0n
|
|
2586
|
-
}
|
|
2587
|
-
];
|
|
2588
|
-
}
|
|
2589
|
-
function buildSettleCalls8(clone) {
|
|
2590
|
-
return [
|
|
2591
|
-
{
|
|
2592
|
-
target: clone,
|
|
2593
|
-
data: encodeFunctionData15({
|
|
2594
|
-
abi: BASE_STRATEGY_ABI,
|
|
2595
|
-
functionName: "settle"
|
|
2596
|
-
}),
|
|
2597
|
-
value: 0n
|
|
2598
|
-
}
|
|
2599
|
-
];
|
|
2600
|
-
}
|
|
2601
|
-
|
|
2602
2053
|
// src/commands/strategy-template.ts
|
|
2603
|
-
import { concat as concat3, numberToHex as numberToHex2 } from "viem";
|
|
2604
2054
|
var ZERO = "0x0000000000000000000000000000000000000000";
|
|
2605
|
-
var ZERO_BYTES323 = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
2606
|
-
function encodeV3Path(tokens, fees) {
|
|
2607
|
-
if (tokens.length !== fees.length + 1) throw new Error("tokens.length must be fees.length + 1");
|
|
2608
|
-
const parts = [];
|
|
2609
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
2610
|
-
parts.push(tokens[i].toLowerCase());
|
|
2611
|
-
if (i < fees.length) {
|
|
2612
|
-
parts.push(numberToHex2(fees[i], { size: 3 }));
|
|
2613
|
-
}
|
|
2614
|
-
}
|
|
2615
|
-
return concat3(parts);
|
|
2616
|
-
}
|
|
2617
|
-
function buildSwapExtraData(network, tokenIn, tokenOut, feeTier, hop, perHopSlippageBps = 100) {
|
|
2618
|
-
if (hop) {
|
|
2619
|
-
const path = encodeV3Path([tokenIn, hop.via, tokenOut], [hop.feeIn, hop.feeOut]);
|
|
2620
|
-
const encoded2 = encodeAbiParameters11(
|
|
2621
|
-
[{ type: "bytes" }, { type: "uint16" }],
|
|
2622
|
-
[path, perHopSlippageBps]
|
|
2623
|
-
);
|
|
2624
|
-
return `0x01${encoded2.slice(2)}`;
|
|
2625
|
-
}
|
|
2626
|
-
const encoded = encodeAbiParameters11([{ type: "uint24" }], [feeTier]);
|
|
2627
|
-
return `0x00${encoded.slice(2)}`;
|
|
2628
|
-
}
|
|
2629
|
-
function parseSwapRouteSpec(spec, token) {
|
|
2630
|
-
const s = spec.trim();
|
|
2631
|
-
const [kind, ...restParts] = s.split(":");
|
|
2632
|
-
const rest = restParts.join(":");
|
|
2633
|
-
switch (kind) {
|
|
2634
|
-
case "v3": {
|
|
2635
|
-
const fee = Number(rest);
|
|
2636
|
-
if (!Number.isInteger(fee) || fee <= 0) throw new Error(`bad v3 fee in '${spec}'`);
|
|
2637
|
-
return v3SingleHopExtraData(fee);
|
|
2638
|
-
}
|
|
2639
|
-
case "v4": {
|
|
2640
|
-
const [feeStr, tsStr] = rest.split(":");
|
|
2641
|
-
const fee = Number(feeStr);
|
|
2642
|
-
const tickSpacing = Number(tsStr);
|
|
2643
|
-
if (!Number.isInteger(fee) || fee <= 0) throw new Error(`bad v4 fee in '${spec}'`);
|
|
2644
|
-
if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) throw new Error(`bad v4 tickSpacing in '${spec}'`);
|
|
2645
|
-
return v4SingleHopExtraData(fee, tickSpacing);
|
|
2646
|
-
}
|
|
2647
|
-
case "v4path": {
|
|
2648
|
-
const hops = rest.split("+").map((hopStr) => {
|
|
2649
|
-
const [currencyRaw, feeTs] = hopStr.split("@");
|
|
2650
|
-
if (!feeTs) throw new Error(`bad v4path hop '${hopStr}' in '${spec}' (expected currency@fee:tickSpacing)`);
|
|
2651
|
-
const [feeStr, tsStr] = feeTs.split(":");
|
|
2652
|
-
const fee = Number(feeStr);
|
|
2653
|
-
const tickSpacing = Number(tsStr);
|
|
2654
|
-
if (!Number.isInteger(fee) || fee <= 0) throw new Error(`bad v4path fee in '${spec}'`);
|
|
2655
|
-
if (!Number.isInteger(tickSpacing) || tickSpacing <= 0) throw new Error(`bad v4path tickSpacing in '${spec}'`);
|
|
2656
|
-
const c = currencyRaw.trim().toLowerCase();
|
|
2657
|
-
let currency;
|
|
2658
|
-
if (c === "eth" || c === "native") currency = ZERO;
|
|
2659
|
-
else if (c === "self") currency = token;
|
|
2660
|
-
else if (isAddress2(currencyRaw.trim())) currency = currencyRaw.trim();
|
|
2661
|
-
else throw new Error(`bad v4path currency '${currencyRaw}' in '${spec}' (use eth/native/self/0x-address)`);
|
|
2662
|
-
return { currency, fee, tickSpacing };
|
|
2663
|
-
});
|
|
2664
|
-
return v4PathExtraData(hops);
|
|
2665
|
-
}
|
|
2666
|
-
default:
|
|
2667
|
-
throw new Error(`unknown swap-route kind '${kind}' in '${spec}' (use v3/v4/v4path)`);
|
|
2668
|
-
}
|
|
2669
|
-
}
|
|
2670
|
-
async function detectSwapRoute(asset, token, preferredFeeTier) {
|
|
2671
|
-
const network = getNetwork();
|
|
2672
|
-
return {
|
|
2673
|
-
extraData: buildSwapExtraData(network, asset, token, preferredFeeTier),
|
|
2674
|
-
routeDesc: `direct (fee ${preferredFeeTier})`
|
|
2675
|
-
};
|
|
2676
|
-
}
|
|
2677
2055
|
var TEMPLATES = [
|
|
2678
2056
|
{
|
|
2679
2057
|
name: "Moonwell Supply",
|
|
@@ -2738,537 +2116,72 @@ function resolveTemplate(key) {
|
|
|
2738
2116
|
}
|
|
2739
2117
|
return { def, address };
|
|
2740
2118
|
}
|
|
2741
|
-
function
|
|
2742
|
-
if (templateKey === "moonwell-supply" || templateKey === "mamo-yield") {
|
|
2743
|
-
if (!opts.amount) return [];
|
|
2744
|
-
const token = opts.token || "USDC";
|
|
2745
|
-
const asset = resolveToken(token);
|
|
2746
|
-
const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
|
|
2747
|
-
return [{ asset, amount: parseUnits(opts.amount, decimals), label: token.toUpperCase() }];
|
|
2748
|
-
}
|
|
2749
|
-
if (templateKey === "venice-inference") {
|
|
2750
|
-
if (!opts.amount) return [];
|
|
2751
|
-
const assetSymbol = opts.asset || "USDC";
|
|
2752
|
-
const asset = resolveToken(assetSymbol);
|
|
2753
|
-
const decimals = assetSymbol.toUpperCase() === "USDC" ? 6 : 18;
|
|
2754
|
-
return [{ asset, amount: parseUnits(opts.amount, decimals), label: assetSymbol.toUpperCase() }];
|
|
2755
|
-
}
|
|
2756
|
-
if (templateKey === "aerodrome-lp") {
|
|
2757
|
-
if (!opts.tokenA || !opts.tokenB || !opts.amountA || !opts.amountB) return [];
|
|
2758
|
-
return [];
|
|
2759
|
-
}
|
|
2760
|
-
if (templateKey === "wsteth-moonwell") {
|
|
2761
|
-
if (!opts.amount) return [];
|
|
2762
|
-
return [{
|
|
2763
|
-
asset: TOKENS().WETH,
|
|
2764
|
-
amount: parseUnits(opts.amount, 18),
|
|
2765
|
-
label: "WETH"
|
|
2766
|
-
}];
|
|
2767
|
-
}
|
|
2768
|
-
if (templateKey === "portfolio") {
|
|
2769
|
-
if (!opts.amount) return [];
|
|
2770
|
-
const assetSymbol = opts.asset || defaultPortfolioAsset();
|
|
2771
|
-
const asset = resolveToken(assetSymbol);
|
|
2772
|
-
const decimals = assetDecimalsForSymbol(assetSymbol);
|
|
2773
|
-
return [{ asset, amount: parseUnits(opts.amount, decimals), label: assetSymbol.toUpperCase() }];
|
|
2774
|
-
}
|
|
2775
|
-
if (templateKey === "hyperliquid-perp" || templateKey === "hyperliquid-grid") {
|
|
2776
|
-
if (!opts.amount) return [];
|
|
2777
|
-
const token = opts.token || "USDC";
|
|
2778
|
-
const asset = resolveToken(token);
|
|
2779
|
-
const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
|
|
2780
|
-
return [{ asset, amount: parseUnits(opts.amount, decimals), label: token.toUpperCase() }];
|
|
2781
|
-
}
|
|
2782
|
-
return [];
|
|
2783
|
-
}
|
|
2784
|
-
function parseAlignedOverrides(raw, expectedLen) {
|
|
2785
|
-
if (raw === void 0) return { values: [], mismatch: false };
|
|
2786
|
-
const values = raw.split(",").map((s) => s.trim());
|
|
2787
|
-
return { values, mismatch: values.length !== expectedLen };
|
|
2788
|
-
}
|
|
2789
|
-
async function buildInitDataForTemplate(templateKey, opts, vault) {
|
|
2790
|
-
if (templateKey === "moonwell-supply") {
|
|
2791
|
-
if (!opts.amount) {
|
|
2792
|
-
console.error(chalk.red("--amount is required for moonwell-supply template"));
|
|
2793
|
-
process.exit(1);
|
|
2794
|
-
}
|
|
2795
|
-
const token = opts.token || "USDC";
|
|
2796
|
-
const underlying = resolveToken(token);
|
|
2797
|
-
const mToken = resolveMToken(token);
|
|
2798
|
-
const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
|
|
2799
|
-
const supplyAmount = parseUnits(opts.amount, decimals);
|
|
2800
|
-
const minRedeem = parseUnits(opts.minRedeem || opts.amount, decimals);
|
|
2801
|
-
const isNativeEthMarket = token.toUpperCase() !== "USDC";
|
|
2802
|
-
return {
|
|
2803
|
-
initData: buildInitData(underlying, mToken, supplyAmount, minRedeem, isNativeEthMarket),
|
|
2804
|
-
asset: underlying,
|
|
2805
|
-
assetAmount: supplyAmount
|
|
2806
|
-
};
|
|
2807
|
-
}
|
|
2119
|
+
async function resolveChainInputsForTemplate(templateKey, opts) {
|
|
2808
2120
|
if (templateKey === "venice-inference") {
|
|
2809
|
-
if (!opts.amount) {
|
|
2810
|
-
console.error(chalk.red("--amount is required for venice-inference template"));
|
|
2811
|
-
process.exit(1);
|
|
2812
|
-
}
|
|
2121
|
+
if (!opts.amount) return {};
|
|
2813
2122
|
const assetSymbol = opts.asset || "USDC";
|
|
2814
2123
|
const asset = resolveToken(assetSymbol);
|
|
2815
2124
|
const vvv = VENICE().VVV;
|
|
2816
2125
|
const isDirect = asset.toLowerCase() === vvv.toLowerCase();
|
|
2817
|
-
const
|
|
2818
|
-
|
|
2819
|
-
const agent = opts.agent || getAccount().address;
|
|
2820
|
-
const isSingleHop = !!opts.singleHop;
|
|
2821
|
-
let minVVV = 0n;
|
|
2822
|
-
if (!isDirect) {
|
|
2823
|
-
if (opts.minVvv) {
|
|
2824
|
-
minVVV = parseUnits(opts.minVvv, 18);
|
|
2825
|
-
} else {
|
|
2826
|
-
const publicClient = getPublicClient();
|
|
2827
|
-
const aeroRouterAbi = [{
|
|
2828
|
-
name: "getAmountsOut",
|
|
2829
|
-
type: "function",
|
|
2830
|
-
stateMutability: "view",
|
|
2831
|
-
inputs: [
|
|
2832
|
-
{ name: "amountIn", type: "uint256" },
|
|
2833
|
-
{ name: "routes", type: "tuple[]", components: [
|
|
2834
|
-
{ name: "from", type: "address" },
|
|
2835
|
-
{ name: "to", type: "address" },
|
|
2836
|
-
{ name: "stable", type: "bool" },
|
|
2837
|
-
{ name: "factory", type: "address" }
|
|
2838
|
-
] }
|
|
2839
|
-
],
|
|
2840
|
-
outputs: [{ name: "amounts", type: "uint256[]" }]
|
|
2841
|
-
}];
|
|
2842
|
-
const routes = isSingleHop ? [{ from: asset, to: vvv, stable: false, factory: AERODROME().FACTORY }] : [
|
|
2843
|
-
{ from: asset, to: TOKENS().WETH, stable: false, factory: AERODROME().FACTORY },
|
|
2844
|
-
{ from: TOKENS().WETH, to: vvv, stable: false, factory: AERODROME().FACTORY }
|
|
2845
|
-
];
|
|
2846
|
-
try {
|
|
2847
|
-
const amounts = await publicClient.readContract({
|
|
2848
|
-
address: AERODROME().ROUTER,
|
|
2849
|
-
abi: aeroRouterAbi,
|
|
2850
|
-
functionName: "getAmountsOut",
|
|
2851
|
-
args: [assetAmount, routes]
|
|
2852
|
-
});
|
|
2853
|
-
const expectedVVV = amounts[amounts.length - 1];
|
|
2854
|
-
minVVV = expectedVVV * 95n / 100n;
|
|
2855
|
-
console.log(chalk.dim(` Auto-quoted minVVV: ${(Number(minVVV) / 1e18).toFixed(4)} VVV (5% slippage on ~${(Number(expectedVVV) / 1e18).toFixed(4)} VVV)`));
|
|
2856
|
-
} catch {
|
|
2857
|
-
console.error(chalk.red("Could not quote USDC\u2192VVV price. Pass --min-vvv <amount> manually."));
|
|
2858
|
-
process.exit(1);
|
|
2859
|
-
}
|
|
2860
|
-
}
|
|
2861
|
-
}
|
|
2862
|
-
const params = {
|
|
2863
|
-
asset,
|
|
2864
|
-
weth: isDirect ? ZERO : TOKENS().WETH,
|
|
2865
|
-
vvv,
|
|
2866
|
-
sVVV: VENICE().STAKING,
|
|
2867
|
-
aeroRouter: isDirect ? ZERO : AERODROME().ROUTER,
|
|
2868
|
-
aeroFactory: isDirect ? ZERO : AERODROME().FACTORY,
|
|
2869
|
-
agent,
|
|
2870
|
-
assetAmount,
|
|
2871
|
-
minVVV,
|
|
2872
|
-
deadlineOffset: 300n,
|
|
2873
|
-
singleHop: isSingleHop
|
|
2126
|
+
const resolved = {
|
|
2127
|
+
veniceAgent: opts.agent || getAccount().address
|
|
2874
2128
|
};
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2129
|
+
if (!isDirect && !opts.minVvv) {
|
|
2130
|
+
const decimals = assetDecimalsForSymbol(assetSymbol);
|
|
2131
|
+
const assetAmount = parseUnits(opts.amount, decimals);
|
|
2132
|
+
const isSingleHop = !!opts.singleHop;
|
|
2133
|
+
const publicClient = getPublicClient();
|
|
2134
|
+
const aeroRouterAbi = [{
|
|
2135
|
+
name: "getAmountsOut",
|
|
2136
|
+
type: "function",
|
|
2137
|
+
stateMutability: "view",
|
|
2138
|
+
inputs: [
|
|
2139
|
+
{ name: "amountIn", type: "uint256" },
|
|
2140
|
+
{ name: "routes", type: "tuple[]", components: [
|
|
2141
|
+
{ name: "from", type: "address" },
|
|
2142
|
+
{ name: "to", type: "address" },
|
|
2143
|
+
{ name: "stable", type: "bool" },
|
|
2144
|
+
{ name: "factory", type: "address" }
|
|
2145
|
+
] }
|
|
2146
|
+
],
|
|
2147
|
+
outputs: [{ name: "amounts", type: "uint256[]" }]
|
|
2148
|
+
}];
|
|
2149
|
+
const routes = isSingleHop ? [{ from: asset, to: vvv, stable: false, factory: AERODROME().FACTORY }] : [
|
|
2150
|
+
{ from: asset, to: TOKENS().WETH, stable: false, factory: AERODROME().FACTORY },
|
|
2151
|
+
{ from: TOKENS().WETH, to: vvv, stable: false, factory: AERODROME().FACTORY }
|
|
2152
|
+
];
|
|
2153
|
+
try {
|
|
2154
|
+
const amounts = await publicClient.readContract({
|
|
2155
|
+
address: AERODROME().ROUTER,
|
|
2156
|
+
abi: aeroRouterAbi,
|
|
2157
|
+
functionName: "getAmountsOut",
|
|
2158
|
+
args: [assetAmount, routes]
|
|
2159
|
+
});
|
|
2160
|
+
const expectedVVV = amounts[amounts.length - 1];
|
|
2161
|
+
const minVVV = expectedVVV * 95n / 100n;
|
|
2162
|
+
console.log(chalk.dim(` Auto-quoted minVVV: ${(Number(minVVV) / 1e18).toFixed(4)} VVV (5% slippage on ~${(Number(expectedVVV) / 1e18).toFixed(4)} VVV)`));
|
|
2163
|
+
resolved.veniceMinVVV = minVVV;
|
|
2164
|
+
} catch {
|
|
2165
|
+
console.error(chalk.red("Could not quote USDC\u2192VVV price. Pass --min-vvv <amount> manually."));
|
|
2885
2166
|
process.exit(1);
|
|
2886
2167
|
}
|
|
2887
2168
|
}
|
|
2888
|
-
|
|
2889
|
-
|
|
2169
|
+
return resolved;
|
|
2170
|
+
}
|
|
2171
|
+
if (templateKey === "aerodrome-lp") {
|
|
2172
|
+
if (!opts.tokenA || !opts.tokenB || !opts.amountA || !opts.amountB || !opts.lpToken) return {};
|
|
2890
2173
|
const publicClient = getPublicClient();
|
|
2891
2174
|
const [decimalsA, decimalsB] = await Promise.all([
|
|
2892
|
-
publicClient.readContract({ address: tokenA, abi: erc20Abi, functionName: "decimals" }),
|
|
2893
|
-
publicClient.readContract({ address: tokenB, abi: erc20Abi, functionName: "decimals" })
|
|
2175
|
+
publicClient.readContract({ address: opts.tokenA, abi: erc20Abi, functionName: "decimals" }),
|
|
2176
|
+
publicClient.readContract({ address: opts.tokenB, abi: erc20Abi, functionName: "decimals" })
|
|
2894
2177
|
]);
|
|
2895
|
-
|
|
2896
|
-
const amountB = parseUnits(opts.amountB, decimalsB);
|
|
2897
|
-
const minAOut = parseUnits(opts.minAOut || "0", decimalsA);
|
|
2898
|
-
const minBOut = parseUnits(opts.minBOut || "0", decimalsB);
|
|
2899
|
-
const params = {
|
|
2900
|
-
tokenA,
|
|
2901
|
-
tokenB,
|
|
2902
|
-
stable: !!opts.stable,
|
|
2903
|
-
factory: AERODROME().FACTORY,
|
|
2904
|
-
router: AERODROME().ROUTER,
|
|
2905
|
-
gauge: opts.gauge || ZERO,
|
|
2906
|
-
lpToken: opts.lpToken,
|
|
2907
|
-
amountADesired: amountA,
|
|
2908
|
-
amountBDesired: amountB,
|
|
2909
|
-
amountAMin: amountA,
|
|
2910
|
-
// use desired as min for now
|
|
2911
|
-
amountBMin: amountB,
|
|
2912
|
-
minAmountAOut: minAOut,
|
|
2913
|
-
minAmountBOut: minBOut
|
|
2914
|
-
};
|
|
2915
|
-
return {
|
|
2916
|
-
initData: buildInitData3(params),
|
|
2917
|
-
asset: tokenA,
|
|
2918
|
-
assetAmount: amountA,
|
|
2919
|
-
extraApprovals: [{ token: tokenB, amount: amountB }]
|
|
2920
|
-
};
|
|
2921
|
-
}
|
|
2922
|
-
if (templateKey === "wsteth-moonwell") {
|
|
2923
|
-
const supplyAmount = opts.amount ? parseUnits(opts.amount, 18) : 0n;
|
|
2924
|
-
const slippageBps = BigInt(opts.slippage || "500");
|
|
2925
|
-
const ONE = 10n ** 18n;
|
|
2926
|
-
const minWstethOutPerWeth = ONE * (10000n - slippageBps) / 10000n;
|
|
2927
|
-
const minWethOutPerWsteth = ONE * (10000n - slippageBps) / 10000n;
|
|
2928
|
-
const params = {
|
|
2929
|
-
weth: TOKENS().WETH,
|
|
2930
|
-
wsteth: TOKENS().wstETH,
|
|
2931
|
-
mwsteth: MOONWELL().mWstETH,
|
|
2932
|
-
aeroRouter: AERODROME().ROUTER,
|
|
2933
|
-
aeroFactory: AERODROME().FACTORY,
|
|
2934
|
-
chainlinkWstethEthFeed: CHAINLINK().WSTETH_ETH_FEED,
|
|
2935
|
-
supplyAmount,
|
|
2936
|
-
minWstethOutPerWeth,
|
|
2937
|
-
minWethOutPerWsteth,
|
|
2938
|
-
deadlineOffset: 300n
|
|
2939
|
-
};
|
|
2940
|
-
return {
|
|
2941
|
-
initData: buildInitData4(params),
|
|
2942
|
-
asset: TOKENS().WETH,
|
|
2943
|
-
assetAmount: supplyAmount
|
|
2944
|
-
};
|
|
2945
|
-
}
|
|
2946
|
-
if (templateKey === "mamo-yield") {
|
|
2947
|
-
if (!opts.amount) {
|
|
2948
|
-
console.error(chalk.red("--amount is required for mamo-yield template"));
|
|
2949
|
-
process.exit(1);
|
|
2950
|
-
}
|
|
2951
|
-
if (!opts.mamoFactory) {
|
|
2952
|
-
console.error(chalk.red("--mamo-factory is required for mamo-yield template"));
|
|
2953
|
-
process.exit(1);
|
|
2954
|
-
}
|
|
2955
|
-
const token = opts.token || "USDC";
|
|
2956
|
-
const underlying = resolveToken(token);
|
|
2957
|
-
const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
|
|
2958
|
-
const amount = parseUnits(opts.amount, decimals);
|
|
2959
|
-
const minRedeemAmount = parseUnits(opts.minRedeem || opts.amount, decimals);
|
|
2960
|
-
return {
|
|
2961
|
-
initData: buildInitData5(underlying, opts.mamoFactory, minRedeemAmount),
|
|
2962
|
-
asset: underlying,
|
|
2963
|
-
assetAmount: amount
|
|
2964
|
-
};
|
|
2178
|
+
return { aerodromeDecimals: { decimalsA, decimalsB } };
|
|
2965
2179
|
}
|
|
2966
|
-
|
|
2967
|
-
let robinhoodDefaultRoute2 = function(token, symbol) {
|
|
2968
|
-
if (network !== "robinhood") return null;
|
|
2969
|
-
if (wethAddr !== ZERO && token.toLowerCase() === wethAddr.toLowerCase()) {
|
|
2970
|
-
return { extraData: v3SingleHopExtraData(500), routeDesc: "v3 direct (fee 500)" };
|
|
2971
|
-
}
|
|
2972
|
-
const r = ROBINHOOD_STOCK_ROUTES[symbol.toUpperCase()];
|
|
2973
|
-
if (r) {
|
|
2974
|
-
return {
|
|
2975
|
-
extraData: v4PathExtraData([
|
|
2976
|
-
{ currency: ZERO, fee: r.nativeFee, tickSpacing: r.nativeTickSpacing },
|
|
2977
|
-
{ currency: token, fee: r.stockFee, tickSpacing: r.stockTickSpacing }
|
|
2978
|
-
]),
|
|
2979
|
-
routeDesc: `v4 multi-hop (USDG\u2192ETH fee ${r.nativeFee} / ts ${r.nativeTickSpacing} \u2192 ${symbol.toUpperCase()} fee ${r.stockFee} / ts ${r.stockTickSpacing})`
|
|
2980
|
-
};
|
|
2981
|
-
}
|
|
2982
|
-
return null;
|
|
2983
|
-
};
|
|
2984
|
-
var robinhoodDefaultRoute = robinhoodDefaultRoute2;
|
|
2985
|
-
if (!opts.amount) {
|
|
2986
|
-
console.error(chalk.red("--amount is required for portfolio template"));
|
|
2987
|
-
process.exit(1);
|
|
2988
|
-
}
|
|
2989
|
-
if (!opts.tokens || !opts.weights) {
|
|
2990
|
-
console.error(chalk.red("--tokens and --weights are required for portfolio template"));
|
|
2991
|
-
console.error(chalk.dim(" --tokens: comma-separated token addresses or symbols"));
|
|
2992
|
-
console.error(chalk.dim(" --weights: comma-separated bps (must sum to 10000)"));
|
|
2993
|
-
process.exit(1);
|
|
2994
|
-
}
|
|
2995
|
-
const network = getNetwork();
|
|
2996
|
-
const tokens = TOKENS();
|
|
2997
|
-
const assetSymbol = opts.asset || defaultPortfolioAsset();
|
|
2998
|
-
const asset = resolveToken(assetSymbol);
|
|
2999
|
-
const decimals = assetDecimalsForSymbol(assetSymbol);
|
|
3000
|
-
const totalAmount = parseUnits(opts.amount, decimals);
|
|
3001
|
-
const maxSlippageBps = Number(opts.maxSlippage || "500");
|
|
3002
|
-
const feeTier = opts.feeTier || "3000";
|
|
3003
|
-
const tokenSpecs = opts.tokens.split(",").map((t) => t.trim());
|
|
3004
|
-
const tokenAddrs = tokenSpecs.map((trimmed) => {
|
|
3005
|
-
if (isAddress2(trimmed)) return trimmed;
|
|
3006
|
-
const allTokens = tokens;
|
|
3007
|
-
const resolved = allTokens[trimmed.toUpperCase()];
|
|
3008
|
-
if (resolved && resolved !== ZERO) return resolved;
|
|
3009
|
-
console.error(chalk.red(`Unknown token: ${trimmed}`));
|
|
3010
|
-
process.exit(1);
|
|
3011
|
-
});
|
|
3012
|
-
const weightsBps = opts.weights.split(",").map((w) => Number(w.trim()));
|
|
3013
|
-
if (tokenAddrs.length !== weightsBps.length) {
|
|
3014
|
-
console.error(chalk.red("--tokens and --weights must have same length"));
|
|
3015
|
-
process.exit(1);
|
|
3016
|
-
}
|
|
3017
|
-
if (weightsBps.reduce((a, b) => a + b, 0) !== 1e4) {
|
|
3018
|
-
console.error(chalk.red(`Weights must sum to 10000`));
|
|
3019
|
-
process.exit(1);
|
|
3020
|
-
}
|
|
3021
|
-
const swapAdapter = opts.swapAdapter || resolveSwapAdapter();
|
|
3022
|
-
const chainlinkVerifier = CHAINLINK().VERIFIER_PROXY;
|
|
3023
|
-
const pushMode = chainlinkVerifier === ZERO;
|
|
3024
|
-
const chainlink = CHAINLINK();
|
|
3025
|
-
const feedIds = parseAlignedOverrides(opts.feedIds, tokenAddrs.length);
|
|
3026
|
-
const feedIdOverrides = feedIds.values;
|
|
3027
|
-
if (feedIds.mismatch) {
|
|
3028
|
-
console.error(chalk.red("--feed-ids must have the same length as --tokens"));
|
|
3029
|
-
process.exit(1);
|
|
3030
|
-
}
|
|
3031
|
-
const priceDecimals = parseAlignedOverrides(opts.priceDecimals, tokenAddrs.length);
|
|
3032
|
-
const priceDecimalOverrides = priceDecimals.values;
|
|
3033
|
-
if (priceDecimals.mismatch) {
|
|
3034
|
-
console.error(chalk.red("--price-decimals must have the same length as --tokens"));
|
|
3035
|
-
process.exit(1);
|
|
3036
|
-
}
|
|
3037
|
-
const swapRoutes = parseAlignedOverrides(opts.swapRoutes, tokenAddrs.length);
|
|
3038
|
-
const swapRouteOverrides = swapRoutes.values;
|
|
3039
|
-
if (swapRoutes.mismatch) {
|
|
3040
|
-
console.error(chalk.red("--swap-routes must have the same length as --tokens"));
|
|
3041
|
-
process.exit(1);
|
|
3042
|
-
}
|
|
3043
|
-
const maxPriceAges = parseAlignedOverrides(opts.maxPriceAges, tokenAddrs.length);
|
|
3044
|
-
const maxPriceAgeOverrides = maxPriceAges.values;
|
|
3045
|
-
if (maxPriceAges.mismatch) {
|
|
3046
|
-
console.error(chalk.red("--max-price-ages must have the same length as --tokens"));
|
|
3047
|
-
process.exit(1);
|
|
3048
|
-
}
|
|
3049
|
-
const wethAddr = TOKENS().WETH;
|
|
3050
|
-
console.log(chalk.dim(" Detecting swap routes..."));
|
|
3051
|
-
const allocations = [];
|
|
3052
|
-
for (let i = 0; i < tokenAddrs.length; i++) {
|
|
3053
|
-
const token = tokenAddrs[i];
|
|
3054
|
-
let route = null;
|
|
3055
|
-
const override = swapRouteOverrides[i];
|
|
3056
|
-
if (override) {
|
|
3057
|
-
try {
|
|
3058
|
-
route = { extraData: parseSwapRouteSpec(override, token), routeDesc: `explicit '${override}'` };
|
|
3059
|
-
} catch (e) {
|
|
3060
|
-
console.error(chalk.red(`Bad --swap-routes entry for ${tokenSpecs[i]}: ${e.message}`));
|
|
3061
|
-
process.exit(1);
|
|
3062
|
-
}
|
|
3063
|
-
}
|
|
3064
|
-
if (!route) route = robinhoodDefaultRoute2(token, tokenSpecs[i]);
|
|
3065
|
-
if (!route && network === "robinhood") {
|
|
3066
|
-
console.error(
|
|
3067
|
-
chalk.red(
|
|
3068
|
-
`No verified default swap route for ${tokenSpecs[i]} on robinhood mainnet.`
|
|
3069
|
-
)
|
|
3070
|
-
);
|
|
3071
|
-
console.error(
|
|
3072
|
-
chalk.yellow(
|
|
3073
|
-
` Pass --swap-routes to set it explicitly for this token, e.g.
|
|
3074
|
-
--swap-routes 'v4path:eth@500:10+self@50000:1000' (USDG\u2192ETH\u2192${tokenSpecs[i].toUpperCase()})`
|
|
3075
|
-
)
|
|
3076
|
-
);
|
|
3077
|
-
process.exit(1);
|
|
3078
|
-
}
|
|
3079
|
-
if (!route) route = await detectSwapRoute(asset, token, Number(feeTier));
|
|
3080
|
-
if (!route) {
|
|
3081
|
-
console.error(chalk.red(`No swap route found for ${token}. No Uniswap V3 pool (direct or via WETH). Pass --swap-routes to set it explicitly.`));
|
|
3082
|
-
process.exit(1);
|
|
3083
|
-
}
|
|
3084
|
-
console.log(chalk.dim(` ${token.slice(0, 10)}... \u2192 ${route.routeDesc}`));
|
|
3085
|
-
let feedId = feedIdOverrides[i];
|
|
3086
|
-
let priceDecimals2 = priceDecimalOverrides[i] ? Number(priceDecimalOverrides[i]) : pushMode ? 8 : 18;
|
|
3087
|
-
const sym = tokenSpecs[i].toUpperCase();
|
|
3088
|
-
let maxPriceAge = 0;
|
|
3089
|
-
if (maxPriceAgeOverrides[i]) {
|
|
3090
|
-
maxPriceAge = Number(maxPriceAgeOverrides[i]);
|
|
3091
|
-
if (!Number.isInteger(maxPriceAge) || maxPriceAge < 0) {
|
|
3092
|
-
console.error(chalk.red(`Bad --max-price-ages entry for ${tokenSpecs[i]}: '${maxPriceAgeOverrides[i]}' (expected a non-negative integer count of seconds)`));
|
|
3093
|
-
process.exit(1);
|
|
3094
|
-
}
|
|
3095
|
-
} else if (pushMode && network === "robinhood") {
|
|
3096
|
-
const { maxPriceAge: age, unknownAddress } = robinhoodEquityMaxAge(
|
|
3097
|
-
tokenSpecs[i],
|
|
3098
|
-
tokens,
|
|
3099
|
-
EQUITY_MAX_PRICE_AGE_SECONDS
|
|
3100
|
-
);
|
|
3101
|
-
maxPriceAge = age;
|
|
3102
|
-
if (unknownAddress && feedIdOverrides[i]) {
|
|
3103
|
-
console.warn(
|
|
3104
|
-
chalk.yellow(
|
|
3105
|
-
` Warning: token ${tokenSpecs[i]} is not in the ${network} registry, so its push feed uses the contract's 26h default max-price-age.
|
|
3106
|
-
If this is a tokenized-equity feed, pass --max-price-ages (e.g. ${EQUITY_MAX_PRICE_AGE_SECONDS}) for this slot or it will trip StalePrice over long weekends.`
|
|
3107
|
-
)
|
|
3108
|
-
);
|
|
3109
|
-
}
|
|
3110
|
-
}
|
|
3111
|
-
if (pushMode && !feedId) {
|
|
3112
|
-
const feedKey = sym === "WETH" || sym === "ETH" ? "ETH_USD_FEED" : `${sym}_USD_FEED`;
|
|
3113
|
-
const feed = isAddress2(tokenSpecs[i]) ? void 0 : chainlink[feedKey];
|
|
3114
|
-
if (!feed || feed === ZERO) {
|
|
3115
|
-
console.error(chalk.red(`No Chainlink push feed for ${tokenSpecs[i]} on ${network}. Pass --feed-ids <feedAddr,...> to supply AggregatorV3 addresses.`));
|
|
3116
|
-
process.exit(1);
|
|
3117
|
-
}
|
|
3118
|
-
feedId = pushFeedId(feed, maxPriceAge);
|
|
3119
|
-
} else if (pushMode && feedId && isAddress2(feedId)) {
|
|
3120
|
-
feedId = pushFeedId(feedId, maxPriceAge);
|
|
3121
|
-
}
|
|
3122
|
-
if (!feedId || feedId === ZERO_BYTES323) {
|
|
3123
|
-
console.error(chalk.red(`Missing Chainlink feedId for allocation ${i} (${tokenSpecs[i]}). The strategy requires a non-zero feedId per token \u2014 pass --feed-ids as a comma-separated list.`));
|
|
3124
|
-
process.exit(1);
|
|
3125
|
-
}
|
|
3126
|
-
allocations.push({
|
|
3127
|
-
token,
|
|
3128
|
-
weightBps: weightsBps[i],
|
|
3129
|
-
swapExtraData: route.extraData,
|
|
3130
|
-
priceDecimals: priceDecimals2,
|
|
3131
|
-
feedId
|
|
3132
|
-
});
|
|
3133
|
-
}
|
|
3134
|
-
return {
|
|
3135
|
-
initData: buildInitData6(asset, swapAdapter, chainlinkVerifier, allocations, totalAmount, maxSlippageBps),
|
|
3136
|
-
asset,
|
|
3137
|
-
assetAmount: totalAmount
|
|
3138
|
-
};
|
|
3139
|
-
}
|
|
3140
|
-
if (templateKey === "hyperliquid-perp") {
|
|
3141
|
-
const token = opts.token || "USDC";
|
|
3142
|
-
const asset = resolveToken(token);
|
|
3143
|
-
const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
|
|
3144
|
-
const depositAmount = opts.amount ? parseUnits(opts.amount, decimals) : 0n;
|
|
3145
|
-
const leverage = Number(opts.leverage || "10");
|
|
3146
|
-
const assetIndex = Number(opts.assetIndex || "0");
|
|
3147
|
-
const maxPosition = parseUnits(opts.maxPosition || "100000", decimals);
|
|
3148
|
-
const maxTradesDay = Number(opts.maxTradesPerDay || "50");
|
|
3149
|
-
return {
|
|
3150
|
-
initData: buildInitData7(asset, depositAmount, assetIndex, leverage, maxPosition, maxTradesDay),
|
|
3151
|
-
asset,
|
|
3152
|
-
assetAmount: depositAmount
|
|
3153
|
-
};
|
|
3154
|
-
}
|
|
3155
|
-
if (templateKey === "hyperliquid-grid") {
|
|
3156
|
-
const token = opts.token || "USDC";
|
|
3157
|
-
const asset = resolveToken(token);
|
|
3158
|
-
const decimals = token.toUpperCase() === "USDC" ? 6 : 18;
|
|
3159
|
-
const depositAmount = opts.amount ? parseUnits(opts.amount, decimals) : 0n;
|
|
3160
|
-
const leverage = Number(opts.leverage || "5");
|
|
3161
|
-
const maxOrderSize = parseUnits(opts.maxOrderSize || "10000", decimals);
|
|
3162
|
-
const maxOrdersPerTick = Number(opts.maxOrdersPerTick || "20");
|
|
3163
|
-
const assetIndices = (opts.assetIndices || "0").split(",").map((s) => Number(s.trim())).filter((n) => !Number.isNaN(n));
|
|
3164
|
-
return {
|
|
3165
|
-
initData: buildInitData8(asset, depositAmount, leverage, maxOrderSize, maxOrdersPerTick, assetIndices),
|
|
3166
|
-
asset,
|
|
3167
|
-
assetAmount: depositAmount
|
|
3168
|
-
};
|
|
3169
|
-
}
|
|
3170
|
-
throw new Error(`No init builder for template: ${templateKey}`);
|
|
2180
|
+
return {};
|
|
3171
2181
|
}
|
|
3172
|
-
function
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
executeCalls: buildExecuteCalls(clone, asset, assetAmount),
|
|
3176
|
-
settleCalls: buildSettleCalls(clone)
|
|
3177
|
-
};
|
|
3178
|
-
}
|
|
3179
|
-
if (templateKey === "venice-inference") {
|
|
3180
|
-
return {
|
|
3181
|
-
executeCalls: buildExecuteCalls2(clone, asset, assetAmount),
|
|
3182
|
-
settleCalls: buildSettleCalls2(clone)
|
|
3183
|
-
};
|
|
3184
|
-
}
|
|
3185
|
-
if (templateKey === "aerodrome-lp") {
|
|
3186
|
-
const tokenB = extraApprovals?.[0]?.token ?? ZERO;
|
|
3187
|
-
const amountB = extraApprovals?.[0]?.amount ?? 0n;
|
|
3188
|
-
return {
|
|
3189
|
-
executeCalls: buildExecuteCalls3(clone, asset, assetAmount, tokenB, amountB),
|
|
3190
|
-
settleCalls: buildSettleCalls3(clone)
|
|
3191
|
-
};
|
|
3192
|
-
}
|
|
3193
|
-
if (templateKey === "wsteth-moonwell") {
|
|
3194
|
-
return {
|
|
3195
|
-
executeCalls: buildExecuteCalls4(clone, asset, assetAmount),
|
|
3196
|
-
settleCalls: buildSettleCalls4(clone)
|
|
3197
|
-
};
|
|
3198
|
-
}
|
|
3199
|
-
if (templateKey === "mamo-yield") {
|
|
3200
|
-
return {
|
|
3201
|
-
executeCalls: buildExecuteCalls5(clone, asset, assetAmount),
|
|
3202
|
-
settleCalls: buildSettleCalls5(clone)
|
|
3203
|
-
};
|
|
3204
|
-
}
|
|
3205
|
-
if (templateKey === "portfolio") {
|
|
3206
|
-
return {
|
|
3207
|
-
executeCalls: buildExecuteCalls6(clone, asset, assetAmount),
|
|
3208
|
-
settleCalls: buildSettleCalls6(clone)
|
|
3209
|
-
};
|
|
3210
|
-
}
|
|
3211
|
-
if (templateKey === "hyperliquid-perp") {
|
|
3212
|
-
return {
|
|
3213
|
-
executeCalls: buildExecuteCalls7(clone, asset, assetAmount),
|
|
3214
|
-
settleCalls: buildSettleCalls7(clone)
|
|
3215
|
-
};
|
|
3216
|
-
}
|
|
3217
|
-
if (templateKey === "hyperliquid-grid") {
|
|
3218
|
-
return {
|
|
3219
|
-
executeCalls: buildExecuteCalls8(clone, asset, assetAmount),
|
|
3220
|
-
settleCalls: buildSettleCalls8(clone)
|
|
3221
|
-
};
|
|
3222
|
-
}
|
|
3223
|
-
throw new Error(`No call builder for template: ${templateKey}`);
|
|
3224
|
-
}
|
|
3225
|
-
function resolveSwapAdapter() {
|
|
3226
|
-
const network = getNetwork();
|
|
3227
|
-
if (network === "robinhood-testnet" && SYNTHRA().ROUTER === ZERO) {
|
|
3228
|
-
console.error(chalk.red("Synthra DEX not available"));
|
|
3229
|
-
process.exit(1);
|
|
3230
|
-
}
|
|
3231
|
-
const adapterAddr = UNISWAP().SWAP_ADAPTER;
|
|
3232
|
-
if (adapterAddr !== ZERO) return adapterAddr;
|
|
3233
|
-
console.error(chalk.red("UniswapSwapAdapter not deployed yet. Use --swap-adapter to specify manually."));
|
|
3234
|
-
process.exit(1);
|
|
3235
|
-
}
|
|
3236
|
-
function resolveToken(symbolOrAddress) {
|
|
3237
|
-
if (isAddress2(symbolOrAddress)) return symbolOrAddress;
|
|
3238
|
-
const upper = symbolOrAddress.toUpperCase();
|
|
3239
|
-
const tokenMap = {
|
|
3240
|
-
...TOKENS(),
|
|
3241
|
-
VVV: VENICE().VVV
|
|
3242
|
-
};
|
|
3243
|
-
const addr = tokenMap[upper];
|
|
3244
|
-
if (!addr || addr === ZERO) {
|
|
3245
|
-
console.error(chalk.red(`Unknown token: ${symbolOrAddress}`));
|
|
3246
|
-
process.exit(1);
|
|
3247
|
-
}
|
|
3248
|
-
return addr;
|
|
3249
|
-
}
|
|
3250
|
-
function defaultPortfolioAsset() {
|
|
3251
|
-
const network = getNetwork();
|
|
3252
|
-
if (network === "robinhood-testnet") return "WETH";
|
|
3253
|
-
return "USDC";
|
|
3254
|
-
}
|
|
3255
|
-
function assetDecimalsForSymbol(symbol) {
|
|
3256
|
-
const upper = symbol.toUpperCase();
|
|
3257
|
-
return upper === "USDC" || upper === "USDG" ? 6 : 18;
|
|
3258
|
-
}
|
|
3259
|
-
function resolveMToken(tokenSymbol) {
|
|
3260
|
-
const upper = tokenSymbol.toUpperCase();
|
|
3261
|
-
const moonwell = MOONWELL();
|
|
3262
|
-
const mTokenMap = {
|
|
3263
|
-
USDC: moonwell.mUSDC,
|
|
3264
|
-
WETH: moonwell.mWETH
|
|
3265
|
-
};
|
|
3266
|
-
const addr = mTokenMap[upper];
|
|
3267
|
-
if (!addr || addr === ZERO) {
|
|
3268
|
-
console.error(chalk.red(`No Moonwell market for: ${tokenSymbol}`));
|
|
3269
|
-
process.exit(1);
|
|
3270
|
-
}
|
|
3271
|
-
return addr;
|
|
2182
|
+
async function resolveAndBuildInitData(templateKey, opts, vault) {
|
|
2183
|
+
const resolved = await resolveChainInputsForTemplate(templateKey, opts);
|
|
2184
|
+
return buildInitDataForTemplate(templateKey, opts, vault, resolved);
|
|
3272
2185
|
}
|
|
3273
2186
|
function serializeCalls(calls) {
|
|
3274
2187
|
return JSON.stringify(
|
|
@@ -3339,7 +2252,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
3339
2252
|
}
|
|
3340
2253
|
const initSpinner = ora("Initializing strategy...").start();
|
|
3341
2254
|
try {
|
|
3342
|
-
const { initData } = await
|
|
2255
|
+
const { initData } = await resolveAndBuildInitData(templateKey, opts, vault);
|
|
3343
2256
|
const account = getAccount();
|
|
3344
2257
|
const initHash = await writeContractWithRetry({
|
|
3345
2258
|
account,
|
|
@@ -3408,7 +2321,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
3408
2321
|
}
|
|
3409
2322
|
const initSpinner = ora("Initializing strategy clone...").start();
|
|
3410
2323
|
try {
|
|
3411
|
-
const { initData } = await
|
|
2324
|
+
const { initData } = await resolveAndBuildInitData(templateKey, opts, vault);
|
|
3412
2325
|
const account = getAccount();
|
|
3413
2326
|
const initHash = await writeContractWithRetry({
|
|
3414
2327
|
account,
|
|
@@ -3519,12 +2432,12 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
3519
2432
|
process.exit(1);
|
|
3520
2433
|
}
|
|
3521
2434
|
if (!opts.agent) opts.agent = proposer;
|
|
3522
|
-
const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-
|
|
2435
|
+
const { parseDuration: parseDuration3, getGovernorOf: getGovernorOf2 } = await import("./governor-PYQQ7QRG.js");
|
|
3523
2436
|
const strategyDuration2 = parseDuration3(opts.duration);
|
|
3524
2437
|
const chainId = getChain().id;
|
|
3525
2438
|
try {
|
|
3526
2439
|
const governor = await getGovernorOf2(vault);
|
|
3527
|
-
const built = await
|
|
2440
|
+
const built = await resolveAndBuildInitData(templateKey, opts, vault);
|
|
3528
2441
|
const deploy = encodeStrategyDeploy(
|
|
3529
2442
|
{
|
|
3530
2443
|
template: templateAddr,
|
|
@@ -3654,7 +2567,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
3654
2567
|
let assetAmount;
|
|
3655
2568
|
let extraApprovals;
|
|
3656
2569
|
try {
|
|
3657
|
-
const built = await
|
|
2570
|
+
const built = await resolveAndBuildInitData(templateKey, opts, vault);
|
|
3658
2571
|
asset = built.asset;
|
|
3659
2572
|
assetAmount = built.assetAmount;
|
|
3660
2573
|
extraApprovals = built.extraApprovals;
|
|
@@ -3745,9 +2658,9 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
3745
2658
|
console.error(chalk.red("Missing --name or --duration. Use --write-calls to skip proposal submission."));
|
|
3746
2659
|
process.exit(1);
|
|
3747
2660
|
}
|
|
3748
|
-
const { propose: propose2 } = await import("./governor-
|
|
2661
|
+
const { propose: propose2 } = await import("./governor-PYQQ7QRG.js");
|
|
3749
2662
|
const { pinJSON } = await import("./ipfs-RWSTXTZM.js");
|
|
3750
|
-
const { parseDuration: parseDuration2 } = await import("./governor-
|
|
2663
|
+
const { parseDuration: parseDuration2 } = await import("./governor-PYQQ7QRG.js");
|
|
3751
2664
|
const strategyDuration = parseDuration2(opts.duration);
|
|
3752
2665
|
const metaSpinner = ora("Pinning metadata to IPFS...").start();
|
|
3753
2666
|
let metadataURI;
|
|
@@ -3770,7 +2683,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
3770
2683
|
process.exit(1);
|
|
3771
2684
|
}
|
|
3772
2685
|
try {
|
|
3773
|
-
const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-
|
|
2686
|
+
const { getAgentFeeBps: getAgentFeeBps2 } = await import("./vault-WDRLJLJ6.js");
|
|
3774
2687
|
const feeBps = await getAgentFeeBps2(vault);
|
|
3775
2688
|
console.log(
|
|
3776
2689
|
chalk.yellow(
|
|
@@ -3858,7 +2771,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
3858
2771
|
let prices = [];
|
|
3859
2772
|
let priceSource = null;
|
|
3860
2773
|
try {
|
|
3861
|
-
const { getTokenPricesInAsset } = await import("./price-
|
|
2774
|
+
const { getTokenPricesInAsset } = await import("./price-DGGB6W2G.js");
|
|
3862
2775
|
prices = await getTokenPricesInAsset({
|
|
3863
2776
|
tokens: allocations.map((a, i) => ({
|
|
3864
2777
|
token: a.token,
|
|
@@ -4107,7 +3020,7 @@ function registerStrategyTemplateCommands(strategy2) {
|
|
|
4107
3020
|
});
|
|
4108
3021
|
const updateSpinner = ora("Updating target weights...").start();
|
|
4109
3022
|
try {
|
|
4110
|
-
const innerData =
|
|
3023
|
+
const innerData = encodeAbiParameters3(
|
|
4111
3024
|
[{ type: "uint256[]" }, { type: "uint256" }, { type: "bytes[]" }],
|
|
4112
3025
|
[newWeightsBps.map((w) => BigInt(w)), BigInt(maxSlip), swapData]
|
|
4113
3026
|
);
|
|
@@ -4288,7 +3201,7 @@ function registerVeniceCommands(program2) {
|
|
|
4288
3201
|
console.log(chalk2.dim(` Key: ${apiKey.slice(0, 8)}...${apiKey.slice(-4)}`));
|
|
4289
3202
|
console.log(chalk2.dim(" Saved to ~/.sherwood/config.json"));
|
|
4290
3203
|
try {
|
|
4291
|
-
const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-
|
|
3204
|
+
const { createVeniceProvisionAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-G4TPLJ6S.js");
|
|
4292
3205
|
const { uid } = await createVeniceProvisionAttestation(account.address);
|
|
4293
3206
|
if (uid !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
|
|
4294
3207
|
console.log(chalk2.dim(` Attested: ${getEasScanUrl2(uid)}`));
|
|
@@ -4510,8 +3423,8 @@ function registerVeniceCommands(program2) {
|
|
|
4510
3423
|
try {
|
|
4511
3424
|
const [assetAddress, totalDeposited, agents] = await Promise.all([
|
|
4512
3425
|
client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "asset" }),
|
|
4513
|
-
|
|
4514
|
-
|
|
3426
|
+
getNetDeposited(vaultAddress),
|
|
3427
|
+
getAgentAddresses(vaultAddress)
|
|
4515
3428
|
]);
|
|
4516
3429
|
const [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
|
|
4517
3430
|
client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
|
|
@@ -4644,10 +3557,10 @@ ${opts.prompt}`;
|
|
|
4644
3557
|
console.log(chalk2.dim(`Model: ${result.model} | Tokens: ${result.usage.promptTokens} in, ${result.usage.completionTokens} out, ${result.usage.totalTokens} total`));
|
|
4645
3558
|
}
|
|
4646
3559
|
try {
|
|
4647
|
-
const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-
|
|
3560
|
+
const { createVeniceInferenceAttestation, getEasScanUrl: getEasScanUrl2 } = await import("./eas-G4TPLJ6S.js");
|
|
4648
3561
|
const { keccak256: keccak2563, toHex, isAddress: isAddr } = await import("viem");
|
|
4649
|
-
const { getChainContracts: getChainContracts2 } = await import("./config-
|
|
4650
|
-
const { getChain: getActiveChain } = await import("./network-
|
|
3562
|
+
const { getChainContracts: getChainContracts2 } = await import("./config-7HU4X7EK.js");
|
|
3563
|
+
const { getChain: getActiveChain } = await import("./network-WU2QC3L4.js");
|
|
4651
3564
|
const vaultRecipient = opts.vault && isAddr(opts.vault) ? opts.vault : getChainContracts2(getActiveChain().id).vault;
|
|
4652
3565
|
const promptHash = keccak2563(toHex(userContent)).slice(0, 18);
|
|
4653
3566
|
const { uid } = await createVeniceInferenceAttestation(
|
|
@@ -4676,7 +3589,7 @@ import chalk3 from "chalk";
|
|
|
4676
3589
|
import ora3 from "ora";
|
|
4677
3590
|
|
|
4678
3591
|
// src/strategies/allowance-disburse.ts
|
|
4679
|
-
import { encodeFunctionData as
|
|
3592
|
+
import { encodeFunctionData as encodeFunctionData8, parseUnits as parseUnits3 } from "viem";
|
|
4680
3593
|
function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minUsdc, swapPath) {
|
|
4681
3594
|
const assetAmount = parseUnits3(config.amount, assetDecimals);
|
|
4682
3595
|
const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
|
|
@@ -4685,7 +3598,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
4685
3598
|
if (!isUsdc) {
|
|
4686
3599
|
calls.push({
|
|
4687
3600
|
target: assetAddress,
|
|
4688
|
-
data:
|
|
3601
|
+
data: encodeFunctionData8({
|
|
4689
3602
|
abi: ERC20_ABI,
|
|
4690
3603
|
functionName: "approve",
|
|
4691
3604
|
args: [UNISWAP().SWAP_ROUTER, assetAmount]
|
|
@@ -4695,7 +3608,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
4695
3608
|
if (isWeth) {
|
|
4696
3609
|
calls.push({
|
|
4697
3610
|
target: UNISWAP().SWAP_ROUTER,
|
|
4698
|
-
data:
|
|
3611
|
+
data: encodeFunctionData8({
|
|
4699
3612
|
abi: SWAP_ROUTER_EXACT_INPUT_SINGLE_ABI,
|
|
4700
3613
|
functionName: "exactInputSingle",
|
|
4701
3614
|
args: [
|
|
@@ -4715,7 +3628,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
4715
3628
|
} else {
|
|
4716
3629
|
calls.push({
|
|
4717
3630
|
target: UNISWAP().SWAP_ROUTER,
|
|
4718
|
-
data:
|
|
3631
|
+
data: encodeFunctionData8({
|
|
4719
3632
|
abi: SWAP_ROUTER_ABI,
|
|
4720
3633
|
functionName: "exactInput",
|
|
4721
3634
|
args: [
|
|
@@ -4735,7 +3648,7 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
4735
3648
|
for (const agent of agents) {
|
|
4736
3649
|
calls.push({
|
|
4737
3650
|
target: TOKENS().USDC,
|
|
4738
|
-
data:
|
|
3651
|
+
data: encodeFunctionData8({
|
|
4739
3652
|
abi: ERC20_ABI,
|
|
4740
3653
|
functionName: "transfer",
|
|
4741
3654
|
args: [agent, perAgent]
|
|
@@ -4750,12 +3663,25 @@ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDec
|
|
|
4750
3663
|
var VALID_FEES = [500, 3e3, 1e4];
|
|
4751
3664
|
function registerAllowanceCommands(program2) {
|
|
4752
3665
|
const allowance = program2.command("allowance").description("Disburse vault profits to agent wallets");
|
|
4753
|
-
allowance.command("disburse").description("Swap vault profits \u2192 USDC \u2192 distribute to all agent operator wallets").requiredOption("--vault <address>", "Vault address").requiredOption("--amount <amount>", "Deposit token amount to convert & distribute (e.g. 500)").option("--fee <tier>", "Fee tier for asset \u2192 USDC swap (500, 3000, 10000)", "3000").option("--slippage <bps>", "Slippage tolerance in bps", "100").option("--execute", "
|
|
3666
|
+
allowance.command("disburse").description("Swap vault profits \u2192 USDC \u2192 distribute to all agent operator wallets").requiredOption("--vault <address>", "Vault address").requiredOption("--amount <amount>", "Deposit token amount to convert & distribute (e.g. 500)").option("--fee <tier>", "Fee tier for asset \u2192 USDC swap (500, 3000, 10000)", "3000").option("--slippage <bps>", "Slippage tolerance in bps", "100").option("--execute", "Unavailable \u2014 the vault has no owner-direct batch path (V-C3); fails with guidance", false).action(async (opts) => {
|
|
4754
3667
|
const vaultAddress = opts.vault;
|
|
4755
3668
|
if (!isAddress4(vaultAddress)) {
|
|
4756
3669
|
console.error(chalk3.red(`Invalid vault address: ${opts.vault}`));
|
|
4757
3670
|
process.exit(1);
|
|
4758
3671
|
}
|
|
3672
|
+
if (opts.execute) {
|
|
3673
|
+
console.error(
|
|
3674
|
+
chalk3.red(
|
|
3675
|
+
"allowance disburse --execute is not available: the vault no longer exposes owner-direct batch execution (executeBatch was removed on-chain, V-C3)."
|
|
3676
|
+
)
|
|
3677
|
+
);
|
|
3678
|
+
console.error(
|
|
3679
|
+
chalk3.dim(
|
|
3680
|
+
"Vault funds can only move through governor-approved batches (executeGovernorBatch via the proposal lifecycle). Run without --execute to simulate the batch."
|
|
3681
|
+
)
|
|
3682
|
+
);
|
|
3683
|
+
process.exit(1);
|
|
3684
|
+
}
|
|
4759
3685
|
const fee = Number(opts.fee);
|
|
4760
3686
|
if (!VALID_FEES.includes(fee)) {
|
|
4761
3687
|
console.error(chalk3.red(`Invalid fee tier. Valid: ${VALID_FEES.join(", ")}`));
|
|
@@ -4773,8 +3699,8 @@ function registerAllowanceCommands(program2) {
|
|
|
4773
3699
|
try {
|
|
4774
3700
|
[assetAddress, totalDeposited, agents] = await Promise.all([
|
|
4775
3701
|
client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "asset" }),
|
|
4776
|
-
|
|
4777
|
-
|
|
3702
|
+
getNetDeposited(vaultAddress),
|
|
3703
|
+
getAgentAddresses(vaultAddress)
|
|
4778
3704
|
]);
|
|
4779
3705
|
[assetDecimals, assetSymbol, assetBalance] = await Promise.all([
|
|
4780
3706
|
client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
|
|
@@ -4801,7 +3727,7 @@ function registerAllowanceCommands(program2) {
|
|
|
4801
3727
|
console.log(` Asset: ${assetSymbol} (${assetDecimals} decimals)`);
|
|
4802
3728
|
console.log(` Amount: ${opts.amount} ${assetSymbol}`);
|
|
4803
3729
|
console.log(` Vault balance: ${formatUnits4(assetBalance, assetDecimals)} ${assetSymbol}`);
|
|
4804
|
-
console.log(`
|
|
3730
|
+
console.log(` Net deposited (est.): ${formatUnits4(totalDeposited, assetDecimals)} ${assetSymbol}`);
|
|
4805
3731
|
console.log(` Profit: ${formatUnits4(profit, assetDecimals)} ${assetSymbol}`);
|
|
4806
3732
|
console.log(` Agents: ${agents.length} (USDC will be split equally)`);
|
|
4807
3733
|
if (!isUsdc) {
|
|
@@ -4868,21 +3794,12 @@ function registerAllowanceCommands(program2) {
|
|
|
4868
3794
|
console.log(chalk3.bold(`Batch calls (${calls.length}):`));
|
|
4869
3795
|
console.log(formatBatch(calls));
|
|
4870
3796
|
console.log();
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
try {
|
|
4878
|
-
const txHash = await executeBatch(calls);
|
|
4879
|
-
execSpinner.succeed(`Batch executed: ${txHash}`);
|
|
4880
|
-
console.log(chalk3.dim(` ${getExplorerUrl(txHash)}`));
|
|
4881
|
-
} catch (err) {
|
|
4882
|
-
execSpinner.fail("Execution failed");
|
|
4883
|
-
console.error(chalk3.red(formatContractError(err)));
|
|
4884
|
-
process.exit(1);
|
|
4885
|
-
}
|
|
3797
|
+
console.log();
|
|
3798
|
+
console.log(
|
|
3799
|
+
chalk3.yellow(
|
|
3800
|
+
"Dry run complete. On-chain execution is unavailable \u2014 the vault has no owner-direct batch path (V-C3); disbursement requires a governor proposal."
|
|
3801
|
+
)
|
|
3802
|
+
);
|
|
4886
3803
|
});
|
|
4887
3804
|
allowance.command("status").description("Show vault profit and agent USDC balances").requiredOption("--vault <address>", "Vault address").action(async (opts) => {
|
|
4888
3805
|
const vaultAddress = opts.vault;
|
|
@@ -4895,8 +3812,8 @@ function registerAllowanceCommands(program2) {
|
|
|
4895
3812
|
try {
|
|
4896
3813
|
const [assetAddress, totalDeposited, agents] = await Promise.all([
|
|
4897
3814
|
client.readContract({ address: vaultAddress, abi: SYNDICATE_VAULT_ABI, functionName: "asset" }),
|
|
4898
|
-
|
|
4899
|
-
|
|
3815
|
+
getNetDeposited(vaultAddress),
|
|
3816
|
+
getAgentAddresses(vaultAddress)
|
|
4900
3817
|
]);
|
|
4901
3818
|
const [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
|
|
4902
3819
|
client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
|
|
@@ -4923,7 +3840,7 @@ function registerAllowanceCommands(program2) {
|
|
|
4923
3840
|
console.log(chalk3.bold("\n Vault"));
|
|
4924
3841
|
console.log(` Asset: ${assetSymbol}`);
|
|
4925
3842
|
console.log(` Balance: ${formatUnits4(assetBalance, assetDecimals)} ${assetSymbol}`);
|
|
4926
|
-
console.log(`
|
|
3843
|
+
console.log(` Net deposited (est.): ${formatUnits4(totalDeposited, assetDecimals)} ${assetSymbol}`);
|
|
4927
3844
|
console.log(` Profit: ${formatUnits4(profit, assetDecimals)} ${assetSymbol}`);
|
|
4928
3845
|
console.log(chalk3.bold("\n Agent USDC Balances"));
|
|
4929
3846
|
for (const { agent, balance } of agentBalances) {
|
|
@@ -4961,18 +3878,12 @@ var IDENTITY_REGISTRY_ABI2 = [
|
|
|
4961
3878
|
}
|
|
4962
3879
|
];
|
|
4963
3880
|
function getAgent0SDK() {
|
|
4964
|
-
const
|
|
4965
|
-
const key = config.privateKey || process.env.PRIVATE_KEY;
|
|
4966
|
-
if (!key) {
|
|
4967
|
-
throw new Error(
|
|
4968
|
-
"Private key not found. Run 'sherwood config set --private-key <key>' or set PRIVATE_KEY env var."
|
|
4969
|
-
);
|
|
4970
|
-
}
|
|
3881
|
+
const key = requirePrivateKey();
|
|
4971
3882
|
const chain = getChain();
|
|
4972
3883
|
const sdkConfig = {
|
|
4973
3884
|
chainId: chain.id,
|
|
4974
3885
|
rpcUrl: getRpcUrl(),
|
|
4975
|
-
privateKey: key
|
|
3886
|
+
privateKey: key
|
|
4976
3887
|
};
|
|
4977
3888
|
if (chain.id !== getChainConfig().chain.id) {
|
|
4978
3889
|
sdkConfig.registryOverrides = {
|
|
@@ -5204,13 +4115,13 @@ function registerIdentityCommands(program2) {
|
|
|
5204
4115
|
}
|
|
5205
4116
|
|
|
5206
4117
|
// src/commands/proposal.ts
|
|
5207
|
-
import { isAddress as isAddress5, encodeFunctionData as
|
|
4118
|
+
import { isAddress as isAddress5, encodeFunctionData as encodeFunctionData10 } from "viem";
|
|
5208
4119
|
import chalk6 from "chalk";
|
|
5209
4120
|
import ora5 from "ora";
|
|
5210
4121
|
import { readFileSync as readFileSync2 } from "fs";
|
|
5211
4122
|
|
|
5212
4123
|
// src/lib/simulate.ts
|
|
5213
|
-
import { decodeFunctionData as decodeFunctionData2, encodeFunctionData as
|
|
4124
|
+
import { decodeFunctionData as decodeFunctionData2, encodeFunctionData as encodeFunctionData9 } from "viem";
|
|
5214
4125
|
import chalk5 from "chalk";
|
|
5215
4126
|
|
|
5216
4127
|
// src/lib/risk.ts
|
|
@@ -5709,14 +4620,9 @@ function safeCall(fn) {
|
|
|
5709
4620
|
return null;
|
|
5710
4621
|
}
|
|
5711
4622
|
}
|
|
5712
|
-
var API_URLS = {
|
|
5713
|
-
"base": "https://app.sherwood.sh",
|
|
5714
|
-
"base-sepolia": "https://testnet.app.sherwood.sh"
|
|
5715
|
-
};
|
|
5716
4623
|
function getApiBaseUrl() {
|
|
5717
4624
|
if (process.env.SHERWOOD_API_URL) return process.env.SHERWOOD_API_URL;
|
|
5718
|
-
|
|
5719
|
-
return API_URLS[chain.testnet ? "base-sepolia" : "base"] || API_URLS["base"];
|
|
4625
|
+
return getChain().testnet ? "https://testnet.sherwood.sh" : "https://www.sherwood.sh";
|
|
5720
4626
|
}
|
|
5721
4627
|
async function simulateViaApi(vault, calls) {
|
|
5722
4628
|
const baseUrl = getApiBaseUrl();
|
|
@@ -5774,7 +4680,7 @@ async function simulateViaApi(vault, calls) {
|
|
|
5774
4680
|
async function simulateViaEthCall(vault, calls) {
|
|
5775
4681
|
const governor = await getGovernorOf(vault);
|
|
5776
4682
|
const client = getPublicClient();
|
|
5777
|
-
const input2 =
|
|
4683
|
+
const input2 = encodeFunctionData9({
|
|
5778
4684
|
abi: SYNDICATE_VAULT_ABI,
|
|
5779
4685
|
functionName: "executeGovernorBatch",
|
|
5780
4686
|
args: [calls.map((c) => ({ target: c.target, data: c.data, value: c.value }))]
|
|
@@ -5902,8 +4808,8 @@ function printSimulationResult(result, callType) {
|
|
|
5902
4808
|
}
|
|
5903
4809
|
async function sendSimulationAlert(subdomain, proposalId, vault, execResult, settleResult) {
|
|
5904
4810
|
try {
|
|
5905
|
-
const xmtp = await import("./xmtp-
|
|
5906
|
-
const { getAccount: getAccount2 } = await import("./client-
|
|
4811
|
+
const xmtp = await import("./xmtp-Q4ZSQV2Q.js");
|
|
4812
|
+
const { getAccount: getAccount2 } = await import("./client-C3C6IXAH.js");
|
|
5907
4813
|
const group = await xmtp.getGroup("", subdomain);
|
|
5908
4814
|
const allRisks = [...execResult.risks, ...settleResult?.risks ?? []];
|
|
5909
4815
|
const criticals = allRisks.filter((r) => r.level === "critical");
|
|
@@ -6586,7 +5492,7 @@ function registerProposalCommands(program2) {
|
|
|
6586
5492
|
process.exit(1);
|
|
6587
5493
|
}
|
|
6588
5494
|
const asset = await getAssetAddress();
|
|
6589
|
-
const noopCalldata =
|
|
5495
|
+
const noopCalldata = encodeFunctionData10({
|
|
6590
5496
|
abi: ERC20_ABI,
|
|
6591
5497
|
functionName: "balanceOf",
|
|
6592
5498
|
args: [vault]
|
|
@@ -8600,13 +7506,13 @@ var GridExecutor = class {
|
|
|
8600
7506
|
import chalk13 from "chalk";
|
|
8601
7507
|
import { mkdir as mkdir3, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "fs/promises";
|
|
8602
7508
|
import { dirname as dirname3 } from "path";
|
|
8603
|
-
import { encodeAbiParameters as
|
|
7509
|
+
import { encodeAbiParameters as encodeAbiParameters5, parseUnits as parseUnits7 } from "viem";
|
|
8604
7510
|
|
|
8605
7511
|
// src/grid/cloid.ts
|
|
8606
|
-
import { keccak256 as keccak2562, encodeAbiParameters as
|
|
7512
|
+
import { keccak256 as keccak2562, encodeAbiParameters as encodeAbiParameters4 } from "viem";
|
|
8607
7513
|
function gridCloid(strategy2, assetIndex, isBuy, levelIndex, nonce) {
|
|
8608
7514
|
const hash = keccak2562(
|
|
8609
|
-
|
|
7515
|
+
encodeAbiParameters4(
|
|
8610
7516
|
[
|
|
8611
7517
|
{ type: "address" },
|
|
8612
7518
|
{ type: "uint32" },
|
|
@@ -8626,11 +7532,11 @@ var UINT64_MAX = 18446744073709551615n;
|
|
|
8626
7532
|
var ACTION_PLACE_GRID = 1;
|
|
8627
7533
|
var ACTION_CANCEL_ALL = 2;
|
|
8628
7534
|
var ACTION_CANCEL_AND_PLACE = 3;
|
|
8629
|
-
function chunkArray(arr,
|
|
8630
|
-
if (
|
|
7535
|
+
function chunkArray(arr, size) {
|
|
7536
|
+
if (size <= 0) throw new Error(`chunk size must be > 0 (got ${size})`);
|
|
8631
7537
|
if (arr.length === 0) return [];
|
|
8632
7538
|
const out = [];
|
|
8633
|
-
for (let i = 0; i < arr.length; i +=
|
|
7539
|
+
for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
|
|
8634
7540
|
return out;
|
|
8635
7541
|
}
|
|
8636
7542
|
var GRID_ORDER_COMPONENTS = [
|
|
@@ -8833,7 +7739,7 @@ var OnchainGridExecutor = class {
|
|
|
8833
7739
|
for (const chunk of chunks) {
|
|
8834
7740
|
const nonce = this.bumpNonce(token);
|
|
8835
7741
|
const { encoded, cloids } = this.encodeOrders(assetIndex, chunk, meta, nonce);
|
|
8836
|
-
const data =
|
|
7742
|
+
const data = encodeAbiParameters5(
|
|
8837
7743
|
[{ type: "uint8" }, { type: "tuple[]", components: [...GRID_ORDER_COMPONENTS] }],
|
|
8838
7744
|
[ACTION_PLACE_GRID, encoded]
|
|
8839
7745
|
);
|
|
@@ -8851,7 +7757,7 @@ var OnchainGridExecutor = class {
|
|
|
8851
7757
|
this.bumpNonce(token);
|
|
8852
7758
|
return "0x";
|
|
8853
7759
|
}
|
|
8854
|
-
const data =
|
|
7760
|
+
const data = encodeAbiParameters5(
|
|
8855
7761
|
[{ type: "uint8" }, { type: "uint32" }, { type: "uint128[]" }],
|
|
8856
7762
|
[ACTION_CANCEL_ALL, assetIndex, cloids]
|
|
8857
7763
|
);
|
|
@@ -8880,7 +7786,7 @@ var OnchainGridExecutor = class {
|
|
|
8880
7786
|
const { encoded, cloids } = this.encodeOrders(assetIndex, chunk, meta, newNonce);
|
|
8881
7787
|
let data;
|
|
8882
7788
|
if (i === 0) {
|
|
8883
|
-
data =
|
|
7789
|
+
data = encodeAbiParameters5(
|
|
8884
7790
|
[
|
|
8885
7791
|
{ type: "uint8" },
|
|
8886
7792
|
{ type: "uint32" },
|
|
@@ -8890,7 +7796,7 @@ var OnchainGridExecutor = class {
|
|
|
8890
7796
|
[ACTION_CANCEL_AND_PLACE, assetIndex, oldCloids, encoded]
|
|
8891
7797
|
);
|
|
8892
7798
|
} else {
|
|
8893
|
-
data =
|
|
7799
|
+
data = encodeAbiParameters5(
|
|
8894
7800
|
[{ type: "uint8" }, { type: "tuple[]", components: [...GRID_ORDER_COMPONENTS] }],
|
|
8895
7801
|
[ACTION_PLACE_GRID, encoded]
|
|
8896
7802
|
);
|
|
@@ -9400,8 +8306,8 @@ function computeDrawdown(curve) {
|
|
|
9400
8306
|
}
|
|
9401
8307
|
function isoToYmdHms(ms) {
|
|
9402
8308
|
const d = new Date(ms);
|
|
9403
|
-
const
|
|
9404
|
-
return `${d.getUTCFullYear()}${
|
|
8309
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8310
|
+
return `${d.getUTCFullYear()}${pad(d.getUTCMonth() + 1)}${pad(d.getUTCDate())}-${pad(d.getUTCHours())}${pad(d.getUTCMinutes())}${pad(d.getUTCSeconds())}`;
|
|
9405
8311
|
}
|
|
9406
8312
|
function makeRunId(fromMs, toMs, config) {
|
|
9407
8313
|
return `bt-${isoToYmdHms(Date.now())}-${shortHash({ fromMs, toMs, config })}`;
|
|
@@ -9740,13 +8646,13 @@ import { join as join4 } from "path";
|
|
|
9740
8646
|
import { homedir as homedir4 } from "os";
|
|
9741
8647
|
import { createHash as createHash2 } from "crypto";
|
|
9742
8648
|
var DEFAULT_SWEEP_DIR = join4(homedir4(), ".sherwood", "grid", "sweeps");
|
|
9743
|
-
function expandSweep(sweep,
|
|
8649
|
+
function expandSweep(sweep, base) {
|
|
9744
8650
|
const fields = ["leverage", "levelsPerSide", "atrMultiplier", "rebalanceDriftPct"];
|
|
9745
8651
|
const valueLists = {
|
|
9746
|
-
leverage: sweep.leverage && sweep.leverage.length > 0 ? sweep.leverage : [
|
|
9747
|
-
levelsPerSide: sweep.levelsPerSide && sweep.levelsPerSide.length > 0 ? sweep.levelsPerSide : [
|
|
9748
|
-
atrMultiplier: sweep.atrMultiplier && sweep.atrMultiplier.length > 0 ? sweep.atrMultiplier : [
|
|
9749
|
-
rebalanceDriftPct: sweep.rebalanceDriftPct && sweep.rebalanceDriftPct.length > 0 ? sweep.rebalanceDriftPct : [
|
|
8652
|
+
leverage: sweep.leverage && sweep.leverage.length > 0 ? sweep.leverage : [base.leverage],
|
|
8653
|
+
levelsPerSide: sweep.levelsPerSide && sweep.levelsPerSide.length > 0 ? sweep.levelsPerSide : [base.levelsPerSide],
|
|
8654
|
+
atrMultiplier: sweep.atrMultiplier && sweep.atrMultiplier.length > 0 ? sweep.atrMultiplier : [base.atrMultiplier],
|
|
8655
|
+
rebalanceDriftPct: sweep.rebalanceDriftPct && sweep.rebalanceDriftPct.length > 0 ? sweep.rebalanceDriftPct : [base.rebalanceDriftPct]
|
|
9750
8656
|
};
|
|
9751
8657
|
let combos = [{}];
|
|
9752
8658
|
for (const field of fields) {
|
|
@@ -9762,8 +8668,8 @@ function expandSweep(sweep, base2) {
|
|
|
9762
8668
|
}
|
|
9763
8669
|
function makeSweepId(opts) {
|
|
9764
8670
|
const d = /* @__PURE__ */ new Date();
|
|
9765
|
-
const
|
|
9766
|
-
const stamp = `${d.getUTCFullYear()}${
|
|
8671
|
+
const pad = (n) => n.toString().padStart(2, "0");
|
|
8672
|
+
const stamp = `${d.getUTCFullYear()}${pad(d.getUTCMonth() + 1)}${pad(d.getUTCDate())}-${pad(d.getUTCHours())}${pad(d.getUTCMinutes())}${pad(d.getUTCSeconds())}`;
|
|
9767
8673
|
const hash = createHash2("sha256").update(JSON.stringify({
|
|
9768
8674
|
fromMs: opts.fromMs,
|
|
9769
8675
|
toMs: opts.toMs,
|
|
@@ -9785,13 +8691,13 @@ async function runSweep(opts) {
|
|
|
9785
8691
|
tokenSplit = {};
|
|
9786
8692
|
for (const t of opts.tokens) tokenSplit[t] = weight;
|
|
9787
8693
|
}
|
|
9788
|
-
const
|
|
8694
|
+
const base = {
|
|
9789
8695
|
...DEFAULT_GRID_CONFIG,
|
|
9790
8696
|
...opts.baseConfig,
|
|
9791
8697
|
tokens: opts.tokens,
|
|
9792
8698
|
tokenSplit
|
|
9793
8699
|
};
|
|
9794
|
-
const combos = expandSweep(opts.sweep,
|
|
8700
|
+
const combos = expandSweep(opts.sweep, base);
|
|
9795
8701
|
if (combos.length === 0) throw new Error("sweep produced no combinations");
|
|
9796
8702
|
const loader = new HistoricalDataLoader({ noCache: opts.noCache });
|
|
9797
8703
|
if (opts.verbose !== false) {
|
|
@@ -9802,7 +8708,7 @@ async function runSweep(opts) {
|
|
|
9802
8708
|
const runs = [];
|
|
9803
8709
|
for (let i = 0; i < combos.length; i++) {
|
|
9804
8710
|
const combo = combos[i];
|
|
9805
|
-
const config = { ...
|
|
8711
|
+
const config = { ...base, ...combo };
|
|
9806
8712
|
const runOutPath = join4(sweepDir, `run-${i.toString().padStart(3, "0")}.json`);
|
|
9807
8713
|
if (opts.verbose !== false) {
|
|
9808
8714
|
process.stderr.write(` [sweep] [${i + 1}/${combos.length}] ${JSON.stringify(combo)}
|
|
@@ -10340,9 +9246,9 @@ try {
|
|
|
10340
9246
|
} catch {
|
|
10341
9247
|
}
|
|
10342
9248
|
var require2 = createRequire(import.meta.url);
|
|
10343
|
-
var CLI_VERSION = "0.
|
|
9249
|
+
var CLI_VERSION = "0.74.2";
|
|
10344
9250
|
async function loadXmtp() {
|
|
10345
|
-
return import("./xmtp-
|
|
9251
|
+
return import("./xmtp-Q4ZSQV2Q.js");
|
|
10346
9252
|
}
|
|
10347
9253
|
async function loadCron() {
|
|
10348
9254
|
return import("./cron-QMLRWDJG.js");
|
|
@@ -10360,6 +9266,10 @@ function validateAddress(value, name) {
|
|
|
10360
9266
|
}
|
|
10361
9267
|
return value;
|
|
10362
9268
|
}
|
|
9269
|
+
function fundShareUrl(subdomain, refParam) {
|
|
9270
|
+
const host = isTestnet() ? "https://testnet.sherwood.sh" : "https://sherwood.sh";
|
|
9271
|
+
return `${host}/fund/${subdomain}${refParam}`;
|
|
9272
|
+
}
|
|
10363
9273
|
function resolveVault(opts) {
|
|
10364
9274
|
if (opts.vault) {
|
|
10365
9275
|
setVaultAddress(validateAddress(opts.vault, "vault"));
|
|
@@ -10540,8 +9450,12 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
10540
9450
|
} catch {
|
|
10541
9451
|
spinner2.text = W6("Creating chat group...");
|
|
10542
9452
|
const groupId = await xmtp.createFundGroup(xmtpClient, subdomain, opts.publicChat);
|
|
10543
|
-
await setTextRecord(subdomain, "xmtpGroupId", groupId, existingInfo.vault);
|
|
10544
9453
|
cacheGroupId(subdomain, groupId);
|
|
9454
|
+
try {
|
|
9455
|
+
await setTextRecord(subdomain, "xmtpGroupId", groupId, existingInfo.vault);
|
|
9456
|
+
} catch {
|
|
9457
|
+
console.log(chalk16.dim(" ENS text record skipped (metadata fallback active)"));
|
|
9458
|
+
}
|
|
10545
9459
|
}
|
|
10546
9460
|
} catch {
|
|
10547
9461
|
console.warn(chalk16.yellow("\n \u26A0 Could not set up XMTP chat group"));
|
|
@@ -10560,7 +9474,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
10560
9474
|
console.log(W6(` ENS: ${G6(`${subdomain}.sherwoodagent.eth`)}`));
|
|
10561
9475
|
console.log(W6(` Chat: ${DIM6(`sherwood chat ${subdomain}`)}`));
|
|
10562
9476
|
const refParam2 = getAgentId() ? `?ref=${getAgentId()}` : "";
|
|
10563
|
-
console.log(W6(` Share: ${G6(
|
|
9477
|
+
console.log(W6(` Share: ${G6(fundShareUrl(subdomain, refParam2))}`));
|
|
10564
9478
|
SEP6();
|
|
10565
9479
|
console.log(G6(" \u2713 Fund saved to ~/.sherwood/config.json (set as primary)"));
|
|
10566
9480
|
console.log();
|
|
@@ -10602,6 +9516,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
10602
9516
|
try {
|
|
10603
9517
|
await setTextRecord(subdomain, "xmtpGroupId", groupId, result.vault);
|
|
10604
9518
|
} catch {
|
|
9519
|
+
console.log(chalk16.dim(" ENS text record skipped (metadata fallback active)"));
|
|
10605
9520
|
}
|
|
10606
9521
|
} catch {
|
|
10607
9522
|
console.warn(chalk16.yellow("\n \u26A0 Could not create XMTP chat group"));
|
|
@@ -10628,7 +9543,7 @@ fund.command("create").description("Create a new fund via the factory (interacti
|
|
|
10628
9543
|
console.log(W6(` Explorer: ${DIM6(getExplorerUrl(result.hash))}`));
|
|
10629
9544
|
console.log(W6(` Chat: ${DIM6(`sherwood chat ${subdomain}`)}`));
|
|
10630
9545
|
const refParam = getAgentId() ? `?ref=${getAgentId()}` : "";
|
|
10631
|
-
console.log(W6(` Share: ${G6(
|
|
9546
|
+
console.log(W6(` Share: ${G6(fundShareUrl(subdomain, refParam))}`));
|
|
10632
9547
|
SEP6();
|
|
10633
9548
|
console.log(G6(" \u2713 Fund saved to ~/.sherwood/config.json (set as primary)"));
|
|
10634
9549
|
console.log();
|
|
@@ -10878,7 +9793,7 @@ fund.command("remove-depositor").description("Remove an address from the deposit
|
|
|
10878
9793
|
});
|
|
10879
9794
|
fund.command("set-agent-fee").description("Set the vault's agent performance fee in bps (vault owner only)").option("--vault <address>", "Vault address (default: from config)").requiredOption(
|
|
10880
9795
|
"--bps <bps>",
|
|
10881
|
-
|
|
9796
|
+
`Agent fee in bps (e.g. 1000 = 10%; max ${MAX_AGENT_FEE_BPS} = ${MAX_AGENT_FEE_BPS / 100}%). The governor clamps the realized fee to its configured maxPerformanceFeeBps, which may be lower.`
|
|
10882
9797
|
).action(async (opts) => {
|
|
10883
9798
|
resolveVault(opts);
|
|
10884
9799
|
const spinner = ora9("Setting agent fee...").start();
|
|
@@ -10934,7 +9849,7 @@ fund.command("add").description("Register an agent on a fund vault (creator only
|
|
|
10934
9849
|
if (opts.agentId) {
|
|
10935
9850
|
agentId = BigInt(opts.agentId);
|
|
10936
9851
|
} else {
|
|
10937
|
-
const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-
|
|
9852
|
+
const { AGENT_REGISTRY: AGENT_REGISTRY2 } = await import("./addresses-OFFTM6NG.js");
|
|
10938
9853
|
const registry = AGENT_REGISTRY2().IDENTITY_REGISTRY;
|
|
10939
9854
|
if (registry === "0x0000000000000000000000000000000000000000") {
|
|
10940
9855
|
agentId = 0n;
|
|
@@ -11010,7 +9925,7 @@ fund.command("share").description("Print the shareable dashboard URL for your fu
|
|
|
11010
9925
|
const fundInfo = await resolveFund(subdomain);
|
|
11011
9926
|
const agentId = getAgentId();
|
|
11012
9927
|
const refParam = agentId ? `?ref=${agentId}` : "";
|
|
11013
|
-
const dashboardUrl =
|
|
9928
|
+
const dashboardUrl = fundShareUrl(subdomain, refParam);
|
|
11014
9929
|
console.log();
|
|
11015
9930
|
console.log(LABEL5(" \u25C6 Share Your Fund"));
|
|
11016
9931
|
SEP6();
|
|
@@ -11659,19 +10574,18 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
|
|
|
11659
10574
|
});
|
|
11660
10575
|
var strategy = program.command("strategy").description("Strategy templates \u2014 list, clone, propose");
|
|
11661
10576
|
registerStrategyTemplateCommands(strategy);
|
|
11662
|
-
program.command("providers").description("List available
|
|
11663
|
-
const {
|
|
11664
|
-
const
|
|
11665
|
-
for (const p of providers) {
|
|
11666
|
-
const info = p.info();
|
|
10577
|
+
program.command("providers").description("List available providers (research + swap routing)").action(async () => {
|
|
10578
|
+
const { listProviders } = await import("./providers-YOOQFBN2.js");
|
|
10579
|
+
for (const info of listProviders()) {
|
|
11667
10580
|
console.log(`
|
|
11668
10581
|
${info.name} (${info.type})`);
|
|
11669
10582
|
console.log(` Capabilities: ${info.capabilities.join(", ")}`);
|
|
11670
|
-
|
|
10583
|
+
const chains = info.supportedChains.map((c) => c.name).join(", ");
|
|
10584
|
+
console.log(` Chains: ${chains || "any (chain-agnostic)"}`);
|
|
11671
10585
|
}
|
|
11672
10586
|
});
|
|
11673
10587
|
try {
|
|
11674
|
-
const { registerChatCommands } = await import("./chat-
|
|
10588
|
+
const { registerChatCommands } = await import("./chat-3PM3GP3C.js");
|
|
11675
10589
|
registerChatCommands(program);
|
|
11676
10590
|
} catch {
|
|
11677
10591
|
program.command("chat <name> [action] [actionArgs...]").description("Fund chat (XMTP) \u2014 requires @xmtp/cli").action(() => {
|
|
@@ -11681,7 +10595,7 @@ try {
|
|
|
11681
10595
|
process.exit(1);
|
|
11682
10596
|
});
|
|
11683
10597
|
}
|
|
11684
|
-
var { registerSessionCommands } = await import("./session-
|
|
10598
|
+
var { registerSessionCommands } = await import("./session-GUVSID3Z.js");
|
|
11685
10599
|
registerSessionCommands(program);
|
|
11686
10600
|
registerVeniceCommands(program);
|
|
11687
10601
|
registerAllowanceCommands(program);
|
|
@@ -11690,11 +10604,11 @@ registerProposalCommands(program);
|
|
|
11690
10604
|
registerQueueCommands(program);
|
|
11691
10605
|
registerGovernorCommands(program);
|
|
11692
10606
|
registerGuardianCommands(program);
|
|
11693
|
-
var { registerResearchCommands } = await import("./research-
|
|
10607
|
+
var { registerResearchCommands } = await import("./research-KX3LCAOQ.js");
|
|
11694
10608
|
registerResearchCommands(program);
|
|
11695
|
-
var { registerAgentCommands } = await import("./agent-
|
|
10609
|
+
var { registerAgentCommands } = await import("./agent-IJOOONON.js");
|
|
11696
10610
|
registerAgentCommands(program);
|
|
11697
|
-
var { registerTradeCommands } = await import("./trade-
|
|
10611
|
+
var { registerTradeCommands } = await import("./trade-WDPMFFYB.js");
|
|
11698
10612
|
registerTradeCommands(program);
|
|
11699
10613
|
registerGridCommand(program);
|
|
11700
10614
|
var configCmd = program.command("config");
|