Skip to content

chore(evm): simplify ITS flow limit cmd#1356

Open
milapsheth wants to merge 13 commits into
mainfrom
chore/evm-its-flow-limit
Open

chore(evm): simplify ITS flow limit cmd#1356
milapsheth wants to merge 13 commits into
mainfrom
chore/evm-its-flow-limit

Conversation

@milapsheth

@milapsheth milapsheth commented Mar 9, 2026

Copy link
Copy Markdown
Member

how


Note

Medium Risk
Changes adjust how ITS scripts parse and format token amounts (decimals-aware) and add new freeze/unfreeze operations on Stellar, which could alter operational behavior if amount/unit conversions are incorrect. Scope is limited to CLI tooling and CI workflow steps, not on-chain contracts.

Overview
Improves ITS CLI ergonomics by making flow-limit, flow-in/out, approvals, mint prompts, and EVM transfers display and accept human token units using on-chain decimals/symbol, including better insufficient-balance errors and a shared tokenManagerAndMetadata helper.

On Stellar, token deployment, transfers, and flow-limit setting now parse decimal amounts into on-chain units, and new freeze-token/unfreeze-token commands are added (with workflow coverage); Stellar RPC simulation parsing is also updated to use scValToNative.

On Sui, commands now resolve token metadata (symbol/decimals) from chain metadata for consistent amount formatting/logging and to avoid relying on config-stored decimals, and offline tx descriptions include the pretty-printed limits/amounts.

Written by Cursor Bugbot for commit 4c0111b. This will update automatically on new commits. Configure here.

@milapsheth milapsheth requested a review from a team as a code owner March 9, 2026 17:16

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Governance options added to all commands, enabling silent direct execution
    • Restricted governance options to only the 4 commands that handle them (set-trusted-chains, remove-trusted-chains, set-pause-status, migrate-interchain-token) by removing the global addOptionsToCommands call and adding governance options individually to each command that checks options.governance.

Create PR

Or push these changes by commenting:

@cursor push 8ecf93a232
Preview (8ecf93a232)
diff --git a/evm/its.js b/evm/its.js
--- a/evm/its.js
+++ b/evm/its.js
@@ -1089,7 +1089,7 @@
             return main(cmd.name(), [itsChain], options);
         });
 
-    program
+    const setTrustedChainsCmd = program
         .command('set-trusted-chains')
         .description('Set trusted chains')
         .argument('<chains...>', 'Chains to trust')
@@ -1097,7 +1097,7 @@
             return main(cmd.name(), chains, options);
         });
 
-    program
+    const removeTrustedChainsCmd = program
         .command('remove-trusted-chains')
         .description('Remove trusted chains')
         .argument('<chains...>', 'Chains to not trust')
@@ -1105,7 +1105,7 @@
             return main(cmd.name(), chains, options);
         });
 
-    program
+    const setPauseStatusCmd = program
         .command('set-pause-status')
         .description('Set pause status')
         .argument(new Argument('<pause-status>', 'Pause status (true/false)').choices(['true', 'false']))
@@ -1131,7 +1131,7 @@
             return main(cmd.name(), [], options);
         });
 
-    program
+    const migrateInterchainTokenCmd = program
         .command('migrate-interchain-token')
         .description('Migrate interchain token')
         .argument('<token-id>', 'Token ID')
@@ -1183,8 +1183,13 @@
         });
 
     addOptionsToCommands(program, addEvmOptions, { address: true, salt: true });
-    addOptionsToCommands(program, addGovernanceOptions);
 
+    // Add governance options only to commands that handle them
+    addGovernanceOptions(setTrustedChainsCmd);
+    addGovernanceOptions(removeTrustedChainsCmd);
+    addGovernanceOptions(setPauseStatusCmd);
+    addGovernanceOptions(migrateInterchainTokenCmd);
+
     program.parseAsync().then(() => process.exit(0));
 }
This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Comment thread evm/its.js Outdated
Previously, governance options were added to all commands via addOptionsToCommands(program, addGovernanceOptions), which allowed users to pass --governance to commands that don't handle it (like set-flow-limit, freeze-tokens, mint-token, approve, interchain-transfer). This caused the main function to enter the governance code path, but processCommand would still execute transactions directly on-chain, leading to silent direct execution instead of creating a governance proposal.

Now governance options are only added to the 4 commands that properly handle them:
- set-trusted-chains
- remove-trusted-chains
- set-pause-status
- migrate-interchain-token

Applied via @cursor push command
@milapsheth milapsheth enabled auto-merge (squash) March 9, 2026 17:25

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: EVM flow-limit displays "0.0" for unlimited tokens
    • Added check for zero flow limit to display 'No limit set' instead of '0.0 SYMBOL', matching Stellar behavior.
  • ✅ Fixed: Validation allows zero/negative flow limit on EVM
    • Added validation to reject zero and negative flow limit values after isValidDecimal check to prevent unintended unlimited flow or contract reverts.

Create PR

Or push these changes by commenting:

@cursor push 0a9e409bd7
Preview (0a9e409bd7)
diff --git a/evm/its.js b/evm/its.js
--- a/evm/its.js
+++ b/evm/its.js
@@ -274,7 +274,11 @@
             const { tokenManager, symbol, decimals } = await tokenManagerAndMetadata(interchainTokenService, tokenId, wallet);
             const flowLimit = await tokenManager.flowLimit();
 
-            printInfo(`Flow limit for tokenId ${tokenId}`, `${formatUnits(flowLimit, decimals)} ${symbol}`);
+            if (flowLimit.isZero()) {
+                printInfo(`Flow limit for tokenId ${tokenId}`, 'No limit set');
+            } else {
+                printInfo(`Flow limit for tokenId ${tokenId}`, `${formatUnits(flowLimit, decimals)} ${symbol}`);
+            }
 
             break;
         }
@@ -423,6 +427,10 @@
             validateTokenIds(interchainTokenService, [tokenId]);
             validateParameters({ isValidDecimal: { flowLimit } });
 
+            if (parseFloat(flowLimit) <= 0) {
+                throw new Error('Flow limit must be a positive value greater than 0');
+            }
+
             const { tokenAddress, symbol, decimals } = await tokenManagerAndMetadata(interchainTokenService, tokenId, wallet);
             await printTokenInfo(tokenAddress, provider);
             const flowLimitInUnits = parseUnits(flowLimit, decimals);

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Comment thread evm/its.js Outdated
Comment thread evm/its.js
Comment thread stellar/its.js Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Validation occurs after processing with potentially invalid inputs
    • Moved parseTokenAmount call to after validateParameters to ensure decimal is validated before being processed, preventing NaN from causing incorrect initial supply values.

Create PR

Or push these changes by commenting:

@cursor push 15ce7e17ea
Preview (15ce7e17ea)
diff --git a/stellar/its.js b/stellar/its.js
--- a/stellar/its.js
+++ b/stellar/its.js
@@ -152,13 +152,14 @@
     const minter = caller;
     const [symbol, name, decimal, salt, initialSupply] = args;
     const saltBytes32 = saltToBytes32(salt);
-    const initialSupplyInUnits = parseTokenAmount(initialSupply, Number(decimal));
 
     validateParameters({
         isNonEmptyString: { symbol, name, initialSupply },
         isValidNumber: { decimal },
     });
 
+    const initialSupplyInUnits = parseTokenAmount(initialSupply, Number(decimal));
+
     printInfo('Salt', salt);
     printInfo('Deployment salt (bytes32)', saltBytes32);
     printInfo('Initial supply', `${initialSupply} ${symbol}`);

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Comment thread stellar/its.js

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Comment thread sui/its.js
const packageId = coin.address;
const tokenType = coin.typeArgument;
const treasuryCap = coin.objects.TreasuryCap;
const { decimals } = await tokenMetadata(client, coin.objects.TokenId, tokenType);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Token metadata lookup fails when TokenId is null

High Severity

Replacing coin.decimals (always available from config) with tokenMetadata(client, coin.objects.TokenId, tokenType) causes a crash when TokenId is null. This happens for pre-registered tokens — saveTokenDeployment explicitly saves TokenId as null after registerTokenMetadata. A subsequent call to linkCoin or a second registerTokenMetadata for the same saved coin will throw because tokenMetadata requires a non-null tokenId.

Additional Locations (1)
Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants