@sherwoodagent/cli 0.88.1 → 0.88.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/index.js CHANGED
@@ -1638,7 +1638,7 @@ function registerStrategyTemplateCommands(strategy2) {
1638
1638
  ]);
1639
1639
  const stateNames = ["Pending", "Executed", "Settled"];
1640
1640
  const stateStr = stateNames[Number(stateRaw)] || `Unknown(${stateRaw})`;
1641
- const [assetDecimals, assetSymbol] = await Promise.all([
1641
+ const [assetDecimals2, assetSymbol] = await Promise.all([
1642
1642
  publicClient.readContract({ address: assetAddr, abi: erc20Abi3, functionName: "decimals" }),
1643
1643
  publicClient.readContract({ address: assetAddr, abi: erc20Abi3, functionName: "symbol" })
1644
1644
  ]);
@@ -1673,19 +1673,19 @@ function registerStrategyTemplateCommands(strategy2) {
1673
1673
  feeTier: feeTiers[i]
1674
1674
  })),
1675
1675
  asset: assetAddr,
1676
- assetDecimals
1676
+ assetDecimals: assetDecimals2
1677
1677
  });
1678
1678
  priceSource = prices.find((p) => p !== null)?.source ?? null;
1679
1679
  } catch {
1680
1680
  }
1681
1681
  const pricesAvailable = prices.some((p) => p !== null);
1682
- const assetBalanceNum = Number(formatUnits5(assetBalance, assetDecimals));
1682
+ const assetBalanceNum = Number(formatUnits5(assetBalance, assetDecimals2));
1683
1683
  let totalPortfolioValue = assetBalanceNum;
1684
1684
  let totalInvested = 0n;
1685
1685
  const allocStatuses = allocations.map((alloc, i) => {
1686
1686
  const [balance, symbol, decimals] = tokenData[i];
1687
1687
  const balanceNum = Number(formatUnits5(balance, decimals));
1688
- const investedNum = Number(formatUnits5(alloc.investedAmount, assetDecimals));
1688
+ const investedNum = Number(formatUnits5(alloc.investedAmount, assetDecimals2));
1689
1689
  totalInvested += alloc.investedAmount;
1690
1690
  const price = prices[i];
1691
1691
  let currentValue = null;
@@ -1700,7 +1700,7 @@ function registerStrategyTemplateCommands(strategy2) {
1700
1700
  targetWeightBps: Number(alloc.targetWeightBps),
1701
1701
  balance: formatUnits5(balance, decimals),
1702
1702
  balanceRaw: balance.toString(),
1703
- investedAmount: formatUnits5(alloc.investedAmount, assetDecimals),
1703
+ investedAmount: formatUnits5(alloc.investedAmount, assetDecimals2),
1704
1704
  currentPrice: price?.price ?? null,
1705
1705
  currentValue,
1706
1706
  actualWeightBps: null,
@@ -1724,7 +1724,7 @@ function registerStrategyTemplateCommands(strategy2) {
1724
1724
  }
1725
1725
  }
1726
1726
  }
1727
- const totalInvestedNum = Number(formatUnits5(totalInvested, assetDecimals));
1727
+ const totalInvestedNum = Number(formatUnits5(totalInvested, assetDecimals2));
1728
1728
  const totalPnl = pricesAvailable ? totalPortfolioValue - totalInvestedNum : null;
1729
1729
  const totalPnlPct = totalPnl !== null && totalInvestedNum > 0 ? totalPnl / totalInvestedNum * 100 : null;
1730
1730
  spinner?.succeed("Strategy state loaded");
@@ -1735,10 +1735,10 @@ function registerStrategyTemplateCommands(strategy2) {
1735
1735
  proposer,
1736
1736
  state: stateStr,
1737
1737
  network,
1738
- asset: { address: assetAddr, symbol: assetSymbol, decimals: assetDecimals },
1739
- totalDeployed: formatUnits5(totalAmount, assetDecimals),
1738
+ asset: { address: assetAddr, symbol: assetSymbol, decimals: assetDecimals2 },
1739
+ totalDeployed: formatUnits5(totalAmount, assetDecimals2),
1740
1740
  maxSlippageBps: Number(maxSlippage),
1741
- assetBalance: formatUnits5(assetBalance, assetDecimals),
1741
+ assetBalance: formatUnits5(assetBalance, assetDecimals2),
1742
1742
  pricesAvailable,
1743
1743
  priceSource,
1744
1744
  portfolio: {
@@ -1763,9 +1763,9 @@ function registerStrategyTemplateCommands(strategy2) {
1763
1763
  console.log(` Proposer: ${chalk4.cyan(proposer)}`);
1764
1764
  console.log(` State: ${stateColor(stateStr)}`);
1765
1765
  console.log(` Asset: ${assetSymbol} (${assetAddr})`);
1766
- console.log(` Deployed: ${formatUnits5(totalAmount, assetDecimals)} ${assetSymbol}`);
1766
+ console.log(` Deployed: ${formatUnits5(totalAmount, assetDecimals2)} ${assetSymbol}`);
1767
1767
  console.log(` Max Slip: ${Number(maxSlippage) / 100}%`);
1768
- console.log(` Asset held: ${formatUnits5(assetBalance, assetDecimals)} ${assetSymbol}`);
1768
+ console.log(` Asset held: ${formatUnits5(assetBalance, assetDecimals2)} ${assetSymbol}`);
1769
1769
  if (pricesAvailable) {
1770
1770
  const pvStr = totalPortfolioValue.toFixed(6);
1771
1771
  const pnlStr = totalPnl !== null ? (totalPnl >= 0 ? "+" : "") + totalPnl.toFixed(6) : "n/a";
@@ -1807,7 +1807,7 @@ function registerStrategyTemplateCommands(strategy2) {
1807
1807
  }
1808
1808
  }
1809
1809
  console.log(chalk4.dim("\u2500".repeat(70)));
1810
- console.log(` Total invested: ${formatUnits5(totalInvested, assetDecimals)} ${assetSymbol}`);
1810
+ console.log(` Total invested: ${formatUnits5(totalInvested, assetDecimals2)} ${assetSymbol}`);
1811
1811
  if (pricesAvailable && maxDriftToken) {
1812
1812
  const absMaxDrift = Math.abs(maxDriftBps);
1813
1813
  const driftColor = absMaxDrift > 500 ? chalk4.red : absMaxDrift > 200 ? chalk4.yellow : chalk4.green;
@@ -1851,7 +1851,7 @@ function registerStrategyTemplateCommands(strategy2) {
1851
1851
  verifySpinner.fail(`Only the proposer (${proposer}) can rebalance. Your wallet: ${account.address}`);
1852
1852
  process.exit(1);
1853
1853
  }
1854
- const [assetDecimals, assetSymbol] = await Promise.all([
1854
+ const [assetDecimals2, assetSymbol] = await Promise.all([
1855
1855
  publicClient.readContract({ address: assetAddr, abi: erc20Abi3, functionName: "decimals" }),
1856
1856
  publicClient.readContract({ address: assetAddr, abi: erc20Abi3, functionName: "symbol" })
1857
1857
  ]);
@@ -1953,7 +1953,7 @@ function registerStrategyTemplateCommands(strategy2) {
1953
1953
  const alloc = postAllocations[i];
1954
1954
  const [balance, symbol, decimals] = postData[i];
1955
1955
  const weightPct = (Number(alloc.targetWeightBps) / 100).toFixed(1) + "%";
1956
- const investedStr = formatUnits5(alloc.investedAmount, assetDecimals);
1956
+ const investedStr = formatUnits5(alloc.investedAmount, assetDecimals2);
1957
1957
  console.log(
1958
1958
  ` ${chalk4.bold(symbol.padEnd(8))} ${weightPct.padEnd(8)} invested: ${investedStr.padEnd(14)} bal: ${formatUnits5(balance, decimals)}`
1959
1959
  );
@@ -2299,7 +2299,7 @@ function registerVeniceCommands(program2) {
2299
2299
  getNetDeposited(vaultAddress),
2300
2300
  getAgentAddresses(vaultAddress)
2301
2301
  ]);
2302
- const [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
2302
+ const [assetDecimals2, assetSymbol, assetBalance] = await Promise.all([
2303
2303
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
2304
2304
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "symbol" }),
2305
2305
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "balanceOf", args: [vaultAddress] })
@@ -2349,7 +2349,7 @@ function registerVeniceCommands(program2) {
2349
2349
  console.log(chalk5.bold("Venice Inference Status"));
2350
2350
  console.log(chalk5.dim("\u2500".repeat(50)));
2351
2351
  console.log(chalk5.bold("\n Vault"));
2352
- console.log(` Profit available: ${formatUnits6(profit, assetDecimals)} ${assetSymbol}`);
2352
+ console.log(` Profit available: ${formatUnits6(profit, assetDecimals2)} ${assetSymbol}`);
2353
2353
  console.log(` VVV (unstaked): ${formatUnits6(vaultVvvBalance, 18)}`);
2354
2354
  console.log(chalk5.bold("\n Agent sVVV Balances"));
2355
2355
  for (const { agent, balance } of agentBalances) {
@@ -2463,8 +2463,8 @@ import ora5 from "ora";
2463
2463
 
2464
2464
  // src/strategies/allowance-disburse.ts
2465
2465
  import { encodeFunctionData, parseUnits as parseUnits6 } from "viem";
2466
- function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minUsdc, swapPath) {
2467
- const assetAmount = parseUnits6(config.amount, assetDecimals);
2466
+ function buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals2, minUsdc, swapPath) {
2467
+ const assetAmount = parseUnits6(config.amount, assetDecimals2);
2468
2468
  const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
2469
2469
  const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
2470
2470
  const calls = [];
@@ -2564,7 +2564,7 @@ function registerAllowanceCommands(program2) {
2564
2564
  const client = getPublicClient();
2565
2565
  const spinner = ora5("Reading vault state...").start();
2566
2566
  let assetAddress;
2567
- let assetDecimals;
2567
+ let assetDecimals2;
2568
2568
  let assetSymbol;
2569
2569
  let totalDeposited;
2570
2570
  let assetBalance;
@@ -2575,7 +2575,7 @@ function registerAllowanceCommands(program2) {
2575
2575
  getNetDeposited(vaultAddress),
2576
2576
  getAgentAddresses(vaultAddress)
2577
2577
  ]);
2578
- [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
2578
+ [assetDecimals2, assetSymbol, assetBalance] = await Promise.all([
2579
2579
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
2580
2580
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "symbol" }),
2581
2581
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "balanceOf", args: [vaultAddress] })
@@ -2590,18 +2590,18 @@ function registerAllowanceCommands(program2) {
2590
2590
  console.error(chalk6.red("No agents registered in vault. Register agents first."));
2591
2591
  process.exit(1);
2592
2592
  }
2593
- const requestedAmount = parseUnits7(opts.amount, assetDecimals);
2593
+ const requestedAmount = parseUnits7(opts.amount, assetDecimals2);
2594
2594
  const profit = assetBalance > totalDeposited ? assetBalance - totalDeposited : 0n;
2595
2595
  const isUsdc = assetAddress.toLowerCase() === TOKENS().USDC.toLowerCase();
2596
2596
  const isWeth = assetAddress.toLowerCase() === TOKENS().WETH.toLowerCase();
2597
2597
  console.log();
2598
2598
  console.log(chalk6.bold("Allowance Disburse"));
2599
2599
  console.log(chalk6.dim("\u2500".repeat(40)));
2600
- console.log(` Asset: ${assetSymbol} (${assetDecimals} decimals)`);
2600
+ console.log(` Asset: ${assetSymbol} (${assetDecimals2} decimals)`);
2601
2601
  console.log(` Amount: ${opts.amount} ${assetSymbol}`);
2602
- console.log(` Vault balance: ${formatUnits7(assetBalance, assetDecimals)} ${assetSymbol}`);
2603
- console.log(` Net deposited (est.): ${formatUnits7(totalDeposited, assetDecimals)} ${assetSymbol}`);
2604
- console.log(` Profit: ${formatUnits7(profit, assetDecimals)} ${assetSymbol}`);
2602
+ console.log(` Vault balance: ${formatUnits7(assetBalance, assetDecimals2)} ${assetSymbol}`);
2603
+ console.log(` Net deposited (est.): ${formatUnits7(totalDeposited, assetDecimals2)} ${assetSymbol}`);
2604
+ console.log(` Profit: ${formatUnits7(profit, assetDecimals2)} ${assetSymbol}`);
2605
2605
  console.log(` Agents: ${agents.length} (USDC will be split equally)`);
2606
2606
  if (!isUsdc) {
2607
2607
  console.log(` Routing: ${isWeth ? `WETH \u2192 USDC (fee ${fee})` : `${assetSymbol} \u2192 WETH \u2192 USDC (fee ${fee})`}`);
@@ -2610,7 +2610,7 @@ function registerAllowanceCommands(program2) {
2610
2610
  console.log(` Vault: ${vaultAddress}`);
2611
2611
  console.log();
2612
2612
  if (requestedAmount > profit) {
2613
- console.warn(chalk6.yellow(` Warning: amount (${opts.amount}) exceeds available profit (${formatUnits7(profit, assetDecimals)})`));
2613
+ console.warn(chalk6.yellow(` Warning: amount (${opts.amount}) exceeds available profit (${formatUnits7(profit, assetDecimals2)})`));
2614
2614
  console.warn(chalk6.yellow(" This will use deposited capital, not just profits."));
2615
2615
  console.log();
2616
2616
  }
@@ -2662,7 +2662,7 @@ function registerAllowanceCommands(program2) {
2662
2662
  fee,
2663
2663
  slippageBps
2664
2664
  };
2665
- const calls = buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals, minUsdc, swapPath);
2665
+ const calls = buildDisburseBatch(config, vaultAddress, agents, assetAddress, assetDecimals2, minUsdc, swapPath);
2666
2666
  console.log();
2667
2667
  console.log(chalk6.bold(`Batch calls (${calls.length}):`));
2668
2668
  console.log(formatBatch(calls));
@@ -2688,7 +2688,7 @@ function registerAllowanceCommands(program2) {
2688
2688
  getNetDeposited(vaultAddress),
2689
2689
  getAgentAddresses(vaultAddress)
2690
2690
  ]);
2691
- const [assetDecimals, assetSymbol, assetBalance] = await Promise.all([
2691
+ const [assetDecimals2, assetSymbol, assetBalance] = await Promise.all([
2692
2692
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "decimals" }),
2693
2693
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "symbol" }),
2694
2694
  client.readContract({ address: assetAddress, abi: ERC20_ABI, functionName: "balanceOf", args: [vaultAddress] })
@@ -2712,9 +2712,9 @@ function registerAllowanceCommands(program2) {
2712
2712
  console.log(chalk6.dim("\u2500".repeat(50)));
2713
2713
  console.log(chalk6.bold("\n Vault"));
2714
2714
  console.log(` Asset: ${assetSymbol}`);
2715
- console.log(` Balance: ${formatUnits7(assetBalance, assetDecimals)} ${assetSymbol}`);
2716
- console.log(` Net deposited (est.): ${formatUnits7(totalDeposited, assetDecimals)} ${assetSymbol}`);
2717
- console.log(` Profit: ${formatUnits7(profit, assetDecimals)} ${assetSymbol}`);
2715
+ console.log(` Balance: ${formatUnits7(assetBalance, assetDecimals2)} ${assetSymbol}`);
2716
+ console.log(` Net deposited (est.): ${formatUnits7(totalDeposited, assetDecimals2)} ${assetSymbol}`);
2717
+ console.log(` Profit: ${formatUnits7(profit, assetDecimals2)} ${assetSymbol}`);
2718
2718
  console.log(chalk6.bold("\n Agent USDC Balances"));
2719
2719
  for (const { agent, balance } of agentBalances) {
2720
2720
  const isMe = agent.toLowerCase() === account.address.toLowerCase();
@@ -3637,7 +3637,7 @@ async function resolveRiskEnvelope(opts, vault) {
3637
3637
  }
3638
3638
  return { maxCapital, maxDrawdownBps };
3639
3639
  }
3640
- function resolveCaps(list, callCount, fallbackTotal, flag) {
3640
+ function resolveCaps(list, callCount, fallbackTotal, flag, decimals) {
3641
3641
  if (list === void 0) {
3642
3642
  if (callCount === 0) return [];
3643
3643
  return Array.from({ length: callCount }, (_, i) => i === callCount - 1 ? fallbackTotal : 0n);
@@ -3649,7 +3649,20 @@ function resolveCaps(list, callCount, fallbackTotal, flag) {
3649
3649
  );
3650
3650
  process.exit(1);
3651
3651
  }
3652
- return parts.map((x) => BigInt(x));
3652
+ return parts.map((x) => {
3653
+ if (!/^\d+(\.\d+)?$/.test(x)) {
3654
+ console.error(chalk8.red(` ${flag} entries must be non-negative decimal amounts in asset units (got "${x}").`));
3655
+ process.exit(1);
3656
+ }
3657
+ return parseUnits8(x, decimals);
3658
+ });
3659
+ }
3660
+ async function assetDecimals(vault) {
3661
+ return await getPublicClient().readContract({
3662
+ address: await getAssetAddress(vault),
3663
+ abi: ERC20_ABI,
3664
+ functionName: "decimals"
3665
+ });
3653
3666
  }
3654
3667
  function registerProposalCommands(program2) {
3655
3668
  const proposal = program2.command("proposal").description("Governance proposals \u2014 create, vote, execute, settle");
@@ -3694,6 +3707,7 @@ function registerProposalCommands(program2) {
3694
3707
  process.exit(1);
3695
3708
  }
3696
3709
  const calldataEnvelope = await resolveRiskEnvelope(opts, vault);
3710
+ const capDecimals2 = await assetDecimals(vault);
3697
3711
  try {
3698
3712
  emitCalldata(
3699
3713
  encodePropose(
@@ -3709,14 +3723,16 @@ function registerProposalCommands(program2) {
3709
3723
  opts.executeCaps,
3710
3724
  executeCalls.length,
3711
3725
  calldataEnvelope.maxCapital,
3712
- "--execute-caps"
3726
+ "--execute-caps",
3727
+ capDecimals2
3713
3728
  ),
3714
3729
  settlementCalls: settleCalls,
3715
3730
  settlementCallCaps: resolveCaps(
3716
3731
  opts.settleCaps,
3717
3732
  settleCalls.length,
3718
3733
  0n,
3719
- "--settle-caps"
3734
+ "--settle-caps",
3735
+ capDecimals2
3720
3736
  )
3721
3737
  },
3722
3738
  getChain().id
@@ -3806,17 +3822,20 @@ function registerProposalCommands(program2) {
3806
3822
  }
3807
3823
  const spinner = ora6({ text: W3("Submitting proposal..."), color: "green" }).start();
3808
3824
  const envelope = await resolveRiskEnvelope(opts, vault);
3825
+ const capDecimals = await assetDecimals(vault);
3809
3826
  const executeCallCaps = resolveCaps(
3810
3827
  opts.executeCaps,
3811
3828
  executeCalls.length,
3812
3829
  envelope.maxCapital,
3813
- "--execute-caps"
3830
+ "--execute-caps",
3831
+ capDecimals
3814
3832
  );
3815
3833
  const settleCallCaps = resolveCaps(
3816
3834
  opts.settleCaps,
3817
3835
  settleCalls.length,
3818
3836
  0n,
3819
- "--settle-caps"
3837
+ "--settle-caps",
3838
+ capDecimals
3820
3839
  );
3821
3840
  try {
3822
3841
  await ensureProposerBondAllowance(vault, envelope.maxCapital, await getAssetAddress(vault));
@@ -8057,7 +8076,7 @@ try {
8057
8076
  } catch {
8058
8077
  }
8059
8078
  var require2 = createRequire(import.meta.url);
8060
- var CLI_VERSION = "0.88.1";
8079
+ var CLI_VERSION = "0.88.2";
8061
8080
  async function loadXmtp() {
8062
8081
  return import("./xmtp-72IRK7JL.js");
8063
8082
  }
@@ -9349,8 +9368,8 @@ vaultCmd.command("balance").description("Show LP share balance and asset value")
9349
9368
  });
9350
9369
  vaultCmd.command("redeem").description("Redeem vault shares for the underlying asset (ERC-4626)").option("--vault <address>", "Vault address (default: from config)").option("--shares <amount>", "Shares to redeem in whole-share units (default: all)").option("--receiver <address>", "Receiver of the underlying asset (default: your wallet)").option("--owner <address>", "Share owner whose shares burn (required with --calldata-only)").action(async (opts) => {
9351
9370
  resolveVault(opts);
9352
- const assetDecimals = await getAssetDecimals();
9353
- const shareDecimals = assetDecimals * 2;
9371
+ const assetDecimals2 = await getAssetDecimals();
9372
+ const shareDecimals = assetDecimals2 * 2;
9354
9373
  if (isCalldataOnly()) {
9355
9374
  if (!opts.shares) {
9356
9375
  console.error(
@@ -9423,7 +9442,7 @@ vaultCmd.command("redeem").description("Redeem vault shares for the underlying a
9423
9442
  );
9424
9443
  spinner.succeed(`Redeemed: ${hash}`);
9425
9444
  console.log(chalk17.dim(` ${getExplorerUrl(hash)}`));
9426
- console.log(` Assets received: ${formatUnits10(assetsOut, assetDecimals)}`);
9445
+ console.log(` Assets received: ${formatUnits10(assetsOut, assetDecimals2)}`);
9427
9446
  } catch (err) {
9428
9447
  spinner.fail("Redeem failed");
9429
9448
  console.error(chalk17.red(formatContractError(err)));