Skip to content

Deploy to production - #817

Merged
ericglau merged 2 commits into
productionfrom
master
Jun 12, 2026
Merged

Deploy to production#817
ericglau merged 2 commits into
productionfrom
master

Conversation

@ericglau

Copy link
Copy Markdown
Member

Includes #812

@ericglau
ericglau requested review from a team as code owners June 11, 2026 17:48
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b7d562bd-f14d-4b7f-8e64-15305510342d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • ✅ Review completed - (🔄 Check again to review again)
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch master

Comment @coderabbitai help to get the list of available commands and usage tips.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Eric Lau <ericglau@outlook.com>
@ericglau
ericglau requested a review from a team June 11, 2026 20:24

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/core/stellar/src/fungible.ts (1)

255-267: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Clamp premint to i128, not u128.

This path validates the scaled premint as u128, but both Base::mint and FungibleVotes::mint receive amount: i128 in this file. A premint that fits u128 but exceeds i128::MAX will still be emitted into the constructor and then fail when the generated Rust code is compiled. The new configurable decimals makes that overflow easier to hit after scaling.

Proposed fix
 function addPremint(c: ContractBuilder, amount: string, decimals: bigint, votes: boolean) {
   if (amount !== undefined && amount !== '0') {
     if (!premintPattern.test(amount)) {
       throw new OptionsError({
         premint: 'Not a valid number',
       });
     }

     // TODO: handle signed int?
-    const premintAbsolute = toUint(getInitialSupply(amount, Number(decimals)), 'premint', 'u128');
+    const premintAbsolute = toUint(getInitialSupply(amount, Number(decimals)), 'premint', 'u128');
+    if (premintAbsolute > (1n << 127n) - 1n) {
+      throw new OptionsError({
+        premint: 'Value is greater than i128 max value',
+      });
+    }

     c.addConstructorArgument({ name: 'recipient', type: 'Address' });
     c.addConstructorCode(`${votes ? 'FungibleVotes' : 'Base'}::mint(e, &recipient, ${premintAbsolute});`);
   }
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/stellar/src/fungible.ts` around lines 255 - 267, The premint
scaling currently uses toUint(...) and emits a u128 literal, but
Base::mint/FungibleVotes::mint expect i128, so change the validation/conversion
in addPremint to use a signed 128-bit conversion (e.g. toInt or equivalent) on
getInitialSupply(amount, Number(decimals)) and produce an i128 value (replace
the toUint call and the u128 target with the signed equivalent) so the generated
constructor argument/premintAbsolute matches i128 range and will fail early if
it exceeds i128::MAX.
packages/ui/src/confidential/ERC7984Controls.svelte (1)

27-38: ⚠️ Potential issue | 🟡 Minor

Enforce ERC7984 wrappable invariants continuously (not just on wrappable toggle)

In packages/ui/src/confidential/ERC7984Controls.svelte the only reset of opts.decimals/opts.premint runs when opts.wrappable !== previousWrappable; if decimals or premint change while opts.wrappable stays true, those invalid values can persist behind disabled inputs. buildERC7984 rejects wrappable with non-default decimals and incompatible premint, so the wizard can end up in an error state with hidden invalid options.

Suggested fix
 let savedDecimals = opts.decimals;
 let savedPremint = opts.premint;
 let previousWrappable = opts.wrappable;
 $: if (opts.wrappable !== previousWrappable) {
   if (opts.wrappable) {
     savedDecimals = opts.decimals;
     savedPremint = opts.premint;
-    opts.decimals = erc7984.defaults.decimals;
-    opts.premint = '';
   } else {
     opts.decimals = savedDecimals;
     opts.premint = savedPremint;
   }
   previousWrappable = opts.wrappable;
 }
+
+$: if (opts.wrappable) {
+  opts.decimals = erc7984.defaults.decimals;
+  opts.premint = '';
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/confidential/ERC7984Controls.svelte` around lines 27 - 38,
The reactive block currently only runs when opts.wrappable changes, so invalid
opts.decimals or opts.premint can persist while opts.wrappable stays true;
modify the logic around
opts.wrappable/previousWrappable/savedDecimals/savedPremint so that whenever
opts.wrappable is true you actively enforce the invariants (e.g., if
opts.wrappable then ensure opts.decimals is set to erc7984.defaults.decimals and
opts.premint is cleared or validated) and when opts.wrappable becomes false
restore savedDecimals/savedPremint; in short, change the reactive check to run
whenever opts.wrappable OR the dependent fields (opts.decimals, opts.premint)
change so the invariant is continuously enforced and buildERC7984 will not
receive invalid hidden values.
🧹 Nitpick comments (5)
packages/common/src/ai/descriptions/stellar.ts (1)

34-37: ⚡ Quick win

stellarStablecoinDescriptions.decimals is added but not wired into the schema contract.

stellarStablecoinSchema currently inherits decimals from stellarFungibleSchema, so this new stablecoin-specific description won’t be surfaced. Either remove this duplicate description key or explicitly override decimals in stellarStablecoinSchema to use stellarStablecoinDescriptions.decimals.

Proposed schema-side fix
 export const stellarStablecoinSchema = {
   ...stellarFungibleSchema,
+  decimals: z.string().optional().describe(stellarStablecoinDescriptions.decimals),
   limitations: z
     .literal(false)
     .or(z.literal('allowlist'))
     .or(z.literal('blocklist'))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/common/src/ai/descriptions/stellar.ts` around lines 34 - 37,
stellarStablecoinDescriptions adds a decimals description but
stellarStablecoinSchema currently inherits decimals from stellarFungibleSchema
so the new description is never used; update stellarStablecoinSchema to
explicitly set/override the decimals field to use
stellarStablecoinDescriptions.decimals (or remove the duplicate key from
stellarStablecoinDescriptions if you prefer) so the stablecoin schema surfaces
the intended description, referencing stellarStablecoinSchema,
stellarFungibleSchema and stellarStablecoinDescriptions.decimals when making the
change.
packages/core/solidity/src/utils/convert-strings.test.ts (1)

45-52: ⚡ Quick win

Add a uint64 boundary case here.

This suite exercises uint8 and uint256, but the new helper also backs ERC7984's uint64 limits in this cohort. A bad uint64 max entry would currently slip through this shared test file.

♻️ Suggested test addition
+test('toUint - uint64 max', t => {
+  t.is(toUint('18446744073709551615', 'foo', 'uint64'), BigInt('18446744073709551615'));
+});
+
+test('toUint - uint64 too large', t => {
+  const error = t.throws(() => toUint('18446744073709551616', 'foo', 'uint64'), {
+    instanceOf: OptionsError,
+  });
+  t.is(error.messages.foo, 'Value is greater than uint64 max value');
+});
+
 test('toUint - uint8', t => {
   t.is(toUint('255', 'foo', 'uint8'), BigInt(255));
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/solidity/src/utils/convert-strings.test.ts` around lines 45 -
52, Add tests covering the uint64 boundary in the same file to ensure toUint
enforces ERC7984 uint64 limits: add a passing case using
toUint('18446744073709551615', 'foo', 'uint64') expecting
BigInt(18446744073709551615) and a failing case calling
toUint('18446744073709551616', 'foo', 'uint64') asserting it throws an
OptionsError with error.messages.foo indicating the value is greater than uint64
max value; reference the existing test names and patterns (e.g., the 'toUint -
uint8' and 'toUint - uint8 too large' tests) and the toUint and OptionsError
symbols to place and implement these new assertions.
packages/core/confidential/src/generate/erc7984.ts (1)

1-10: ⚡ Quick win

Derive blueprint decimals from the exported builder constants.

'6' and '10' duplicate the runtime contract in erc7984.ts, so a later change to DEFAULT_DECIMALS or MAX_DECIMALS can desync generated fixtures from builder validation.

♻️ Proposed fix
-import { DEFAULT_DECIMALS, type ERC7984Options } from '../erc7984';
+import { DEFAULT_DECIMALS, MAX_DECIMALS, type ERC7984Options } from '../erc7984';
@@
-  decimals: ['6', '10'],
+  decimals: [DEFAULT_DECIMALS.toString(), MAX_DECIMALS.toString()],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/confidential/src/generate/erc7984.ts` around lines 1 - 10,
Replace the hardcoded decimals entries in the blueprint object with values
derived from the exported builder constants: use DEFAULT_DECIMALS and
MAX_DECIMALS (convert to strings) instead of the literal '6' and '10'. Update
the decimals field in the blueprint (variable name: blueprint, property:
decimals) to compute its array from the imported constants so future changes to
DEFAULT_DECIMALS/MAX_DECIMALS stay in sync with the generated fixtures and the
ERC7984 builder validation.
packages/core/confidential/src/erc7984.test.ts (1)

139-151: ⚡ Quick win

Add one premint-overflow case with non-default decimals.

The new overflow path now depends on the configured decimals, but the current assertions only lock the default-6 case. A decimals: '10' overflow test would cover the branch this change introduced.

Also applies to: 179-192

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/confidential/src/erc7984.test.ts` around lines 139 - 151, Add a
second test case alongside the existing "erc7984 premint more precise than
decimals" that specifically exercises the overflow branch for non-default
decimals: call buildERC7984 with decimals: '10' and a premint string that has
more precision or magnitude than allowed by 10 decimals (e.g., a value that
would overflow when scaled), then assert (error as
OptionsError).messages.premint equals 'Too many decimals' (mirror the existing
assertion). Do the same addition for the similar test block referenced around
the other case (the block at 179-192) so both the precision and overflow
branches for custom decimals are covered, using the same identifiers
buildERC7984, OptionsError and messages.premint to locate the tests.
packages/core/confidential/src/zip-hardhat.test.ts (1)

45-65: ⚡ Quick win

Exercise a non-default decimals fixture in the Hardhat integration test.

This suite is the compile-time safety net for emitted contracts, but it still only covers the default-decimals path. Adding one decimals !== '6' case would validate the new decimals() override and premint scaling end to end.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/confidential/src/zip-hardhat.test.ts` around lines 45 - 65, The
test currently only exercises the default decimals path; add another serial test
(similar to the existing test.serial block) that builds an ERC7984 options set
with decimals set to a non-default value (e.g., decimals: '8') and appropriate
premint value to validate premint scaling, then call buildERC7984(opts) and
await runIgnitionTest(c, t); reference the same types (ERC7984Options,
GenericOptions) and functions (buildERC7984, runIgnitionTest, test.serial) so
the Hardhat integration covers the decimals() override end-to-end.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/core/stellar/src/fungible.ts`:
- Around line 255-267: The premint scaling currently uses toUint(...) and emits
a u128 literal, but Base::mint/FungibleVotes::mint expect i128, so change the
validation/conversion in addPremint to use a signed 128-bit conversion (e.g.
toInt or equivalent) on getInitialSupply(amount, Number(decimals)) and produce
an i128 value (replace the toUint call and the u128 target with the signed
equivalent) so the generated constructor argument/premintAbsolute matches i128
range and will fail early if it exceeds i128::MAX.

In `@packages/ui/src/confidential/ERC7984Controls.svelte`:
- Around line 27-38: The reactive block currently only runs when opts.wrappable
changes, so invalid opts.decimals or opts.premint can persist while
opts.wrappable stays true; modify the logic around
opts.wrappable/previousWrappable/savedDecimals/savedPremint so that whenever
opts.wrappable is true you actively enforce the invariants (e.g., if
opts.wrappable then ensure opts.decimals is set to erc7984.defaults.decimals and
opts.premint is cleared or validated) and when opts.wrappable becomes false
restore savedDecimals/savedPremint; in short, change the reactive check to run
whenever opts.wrappable OR the dependent fields (opts.decimals, opts.premint)
change so the invariant is continuously enforced and buildERC7984 will not
receive invalid hidden values.

---

Nitpick comments:
In `@packages/common/src/ai/descriptions/stellar.ts`:
- Around line 34-37: stellarStablecoinDescriptions adds a decimals description
but stellarStablecoinSchema currently inherits decimals from
stellarFungibleSchema so the new description is never used; update
stellarStablecoinSchema to explicitly set/override the decimals field to use
stellarStablecoinDescriptions.decimals (or remove the duplicate key from
stellarStablecoinDescriptions if you prefer) so the stablecoin schema surfaces
the intended description, referencing stellarStablecoinSchema,
stellarFungibleSchema and stellarStablecoinDescriptions.decimals when making the
change.

In `@packages/core/confidential/src/erc7984.test.ts`:
- Around line 139-151: Add a second test case alongside the existing "erc7984
premint more precise than decimals" that specifically exercises the overflow
branch for non-default decimals: call buildERC7984 with decimals: '10' and a
premint string that has more precision or magnitude than allowed by 10 decimals
(e.g., a value that would overflow when scaled), then assert (error as
OptionsError).messages.premint equals 'Too many decimals' (mirror the existing
assertion). Do the same addition for the similar test block referenced around
the other case (the block at 179-192) so both the precision and overflow
branches for custom decimals are covered, using the same identifiers
buildERC7984, OptionsError and messages.premint to locate the tests.

In `@packages/core/confidential/src/generate/erc7984.ts`:
- Around line 1-10: Replace the hardcoded decimals entries in the blueprint
object with values derived from the exported builder constants: use
DEFAULT_DECIMALS and MAX_DECIMALS (convert to strings) instead of the literal
'6' and '10'. Update the decimals field in the blueprint (variable name:
blueprint, property: decimals) to compute its array from the imported constants
so future changes to DEFAULT_DECIMALS/MAX_DECIMALS stay in sync with the
generated fixtures and the ERC7984 builder validation.

In `@packages/core/confidential/src/zip-hardhat.test.ts`:
- Around line 45-65: The test currently only exercises the default decimals
path; add another serial test (similar to the existing test.serial block) that
builds an ERC7984 options set with decimals set to a non-default value (e.g.,
decimals: '8') and appropriate premint value to validate premint scaling, then
call buildERC7984(opts) and await runIgnitionTest(c, t); reference the same
types (ERC7984Options, GenericOptions) and functions (buildERC7984,
runIgnitionTest, test.serial) so the Hardhat integration covers the decimals()
override end-to-end.

In `@packages/core/solidity/src/utils/convert-strings.test.ts`:
- Around line 45-52: Add tests covering the uint64 boundary in the same file to
ensure toUint enforces ERC7984 uint64 limits: add a passing case using
toUint('18446744073709551615', 'foo', 'uint64') expecting
BigInt(18446744073709551615) and a failing case calling
toUint('18446744073709551616', 'foo', 'uint64') asserting it throws an
OptionsError with error.messages.foo indicating the value is greater than uint64
max value; reference the existing test names and patterns (e.g., the 'toUint -
uint8' and 'toUint - uint8 too large' tests) and the toUint and OptionsError
symbols to place and implement these new assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: fe8f4306-b148-43e5-be8e-2b5fffe3aac4

📥 Commits

Reviewing files that changed from the base of the PR and between d0bc91f and 4f50cc9.

⛔ Files ignored due to path filters (7)
  • packages/cli/src/cli.test.ts.snap is excluded by !**/*.snap
  • packages/core/confidential/src/erc7984.test.ts.snap is excluded by !**/*.snap
  • packages/core/solidity/src/erc20.test.ts.snap is excluded by !**/*.snap
  • packages/core/solidity/src/stablecoin.test.ts.snap is excluded by !**/*.snap
  • packages/core/stellar/src/fungible.test.ts.snap is excluded by !**/*.snap
  • packages/core/stellar/src/stablecoin.test.ts.snap is excluded by !**/*.snap
  • packages/mcp/src/confidential/tools/erc7984.test.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (66)
  • .changeset/bump-stellar-contracts.md
  • .changeset/erc7984-wrappable-premint.md
  • .changeset/hardhat-3-sample-project.md
  • packages/cli/CHANGELOG.md
  • packages/cli/package.json
  • packages/cli/src/cli.test.ts.md
  • packages/common/CHANGELOG.md
  • packages/common/package.json
  • packages/common/src/ai/descriptions/confidential.ts
  • packages/common/src/ai/descriptions/solidity.ts
  • packages/common/src/ai/descriptions/stellar.ts
  • packages/common/src/ai/schemas/confidential.ts
  • packages/common/src/ai/schemas/solidity.ts
  • packages/common/src/ai/schemas/stellar.ts
  • packages/core/confidential/CHANGELOG.md
  • packages/core/confidential/package.json
  • packages/core/confidential/src/erc7984.test.ts
  • packages/core/confidential/src/erc7984.test.ts.md
  • packages/core/confidential/src/erc7984.ts
  • packages/core/confidential/src/generate/erc7984.ts
  • packages/core/confidential/src/zip-hardhat.test.ts
  • packages/core/solidity/CHANGELOG.md
  • packages/core/solidity/package.json
  • packages/core/solidity/src/erc20.test.ts
  • packages/core/solidity/src/erc20.test.ts.md
  • packages/core/solidity/src/erc20.ts
  • packages/core/solidity/src/generate/erc20.ts
  • packages/core/solidity/src/generate/stablecoin.ts
  • packages/core/solidity/src/index.ts
  • packages/core/solidity/src/stablecoin.test.ts
  • packages/core/solidity/src/stablecoin.test.ts.md
  • packages/core/solidity/src/utils/convert-strings.test.ts
  • packages/core/solidity/src/utils/convert-strings.ts
  • packages/core/stellar/CHANGELOG.md
  • packages/core/stellar/package.json
  • packages/core/stellar/src/fungible.test.ts
  • packages/core/stellar/src/fungible.test.ts.md
  • packages/core/stellar/src/fungible.ts
  • packages/core/stellar/src/generate/fungible.ts
  • packages/core/stellar/src/generate/stablecoin.ts
  • packages/core/stellar/src/stablecoin.test.ts
  • packages/core/stellar/src/stablecoin.test.ts.md
  • packages/mcp/CHANGELOG.md
  • packages/mcp/package.json
  • packages/mcp/src/confidential/tools/erc7984.test.ts
  • packages/mcp/src/confidential/tools/erc7984.test.ts.md
  • packages/mcp/src/confidential/tools/erc7984.ts
  • packages/mcp/src/solidity/tools/erc20.test.ts
  • packages/mcp/src/solidity/tools/erc20.ts
  • packages/mcp/src/solidity/tools/rwa.test.ts
  • packages/mcp/src/solidity/tools/rwa.ts
  • packages/mcp/src/solidity/tools/stablecoin.test.ts
  • packages/mcp/src/solidity/tools/stablecoin.ts
  • packages/mcp/src/stellar/tools/fungible.test.ts
  • packages/mcp/src/stellar/tools/fungible.ts
  • packages/mcp/src/stellar/tools/stablecoin.test.ts
  • packages/mcp/src/stellar/tools/stablecoin.ts
  • packages/ui/api/ai-assistant/function-definitions/confidential.ts
  • packages/ui/api/ai-assistant/function-definitions/solidity.ts
  • packages/ui/api/ai-assistant/function-definitions/stellar.ts
  • packages/ui/src/confidential/ERC7984Controls.svelte
  • packages/ui/src/solidity/ERC20Controls.svelte
  • packages/ui/src/solidity/RealWorldAssetControls.svelte
  • packages/ui/src/solidity/StablecoinControls.svelte
  • packages/ui/src/stellar/FungibleControls.svelte
  • packages/ui/src/stellar/StablecoinControls.svelte
💤 Files with no reviewable changes (3)
  • .changeset/hardhat-3-sample-project.md
  • .changeset/erc7984-wrappable-premint.md
  • .changeset/bump-stellar-contracts.md

@son-oz son-oz 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.

lgtm

@ericglau
ericglau merged commit acfe8aa into production Jun 12, 2026
43 of 45 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants