- 
                Notifications
    You must be signed in to change notification settings 
- Fork 60
chore: update contracts to use abstract universal contract #299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| 📝 WalkthroughWalkthroughThis PR removes direct gateway state and constructor parameters from multiple example contracts, reorders/simplifies initialize signatures and test calls, updates toolchain configs and dependency versions, and consolidates shell scripts and deployment argument handling across examples. Changes
 Sequence Diagram(s)sequenceDiagram
    participant Test
    participant Contract
    participant Parent as UniversalContract
    Note over Test,Contract: Prior flow — contract stored gateway locally
    Test->>Contract: new Contract(payable(gateway))
    Contract->>Contract: store gateway
    Test->>Contract: onCall(...)
    Contract->>Contract: onlyGateway() local check
    Note over Test,Contract: New flow — no local gateway, rely on inherited access control
    Test->>Contract: new Contract()
    Test->>Contract: onCall(...)
    Contract->>Parent: delegate authorization (onlyGateway)
    Parent-->>Contract: authorization result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~45 minutes 
 Pre-merge checks and finishing touches❌ Failed checks (1 warning)
 ✅ Passed checks (2 passed)
 ✨ Finishing touches🧪 Generate unit tests (beta)
 📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro Disabled knowledge base sources: 
 
 ⛔ Files ignored due to path filters (1)
 📒 Files selected for processing (1)
 🚧 Files skipped from review as they are similar to previous changes (1)
 ⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment  | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️  Outside diff range comments (6)
examples/nft/scripts/localnet.sh (1)
35-39: Missing required--gatewayparameter for ZetaChainUniversalNFT deployment.The
deploycommand requires the--gatewayparameter for all Universal NFT deployments. The ZetaChainUniversalNFT deployment at lines 35–39 is missing this parameter despiteGATEWAY_ZETACHAINbeing fetched at line 28. The Ethereum and BNB deployments correctly pass--gatewayat lines 48–54 and 56–62 respectively.Add
--gateway "$GATEWAY_ZETACHAIN"to the ZetaChainUniversalNFT deployment command (lines 35–39):CONTRACT_ZETACHAIN=$(npx tsx commands deploy \ --rpc "$RPC" \ --private-key "$PRIVATE_KEY" \ --name ZetaChainUniversalNFT \ --gateway "$GATEWAY_ZETACHAIN" \ --gas-limit 1000000 | jq -r '.contractAddress')examples/messaging/package.json (1)
2-4: Package metadata appears inconsistent with directory structure.The package name is "nft" and the description references "Universal NFT", but this file is located in
examples/messaging/package.json. This suggests either incorrect package metadata or a file organization issue.Verify that the package name and description accurately reflect the purpose of this example. If this is indeed a messaging example, update the metadata accordingly:
- "name": "nft", + "name": "messaging", "version": "1.0.0", - "description": "Universal NFT enables non-fungible ERC-721 tokens to minted and transferred between connected chains.", + "description": "Messaging example for cross-chain communication.",examples/swap/commands/deploy.ts (1)
83-86: Remove unused gateway CLI option.The
--gatewayoption is defined in the CLI interface but is no longer used in the deployment logic after removing the gateway parameter from the initialize function. This dead code should be removed to avoid confusion.- .option( - "-g, --gateway <address>", - "Gateway address (default: testnet)", - "0x6c533f7fe93fae114d0954697069df33c9b74fd7" - ) .option("--gas-limit <number>", "Gas limit for the transaction", "1000000")examples/nft/contracts/EVMUniversalNFT.sol (1)
48-48: Fix EVMUniversalNFT.sol line 48: incorrect number of parameters passed to__UniversalNFTCore_init.The initializer signature accepts a single
uint256 gasLimitparameter, but the current call passes three arguments:gatewayAddress,address(this), andgas. This will cause a compilation error.Correct the call to:
__UniversalNFTCore_init(gas);This aligns with the correct implementation already present in ZetaChainUniversalNFT.sol (line 47) and matches the external contract specification.
examples/swap/contracts/Swap.sol (1)
197-241: Swap.sol is missing thegatewayvariable andonlyGatewaymodifier declarations, causing compilation errors.The
withdraw()function referencesgatewayon lines 207, 211, 214, and 218, and theonCall()function uses theonlyGatewaymodifier, but neither the variable nor the modifier are declared in Swap.sol.UniversalContractprovides only theonCall()method and does not supply agatewayproperty.The Connected.sol example demonstrates the correct pattern:
GatewayZEVM public immutable gateway; constructor(address payable gatewayAddress) { gateway = GatewayEVM(gatewayAddress); } modifier onlyGateway() { if (msg.sender != address(gateway)) revert Unauthorized(); }Add the gateway state variable and onlyGateway modifier to Swap.sol. Initialize
gatewayin theinitialize()function to align with the upgradeable proxy pattern used in this contract, or add a constructor parameter and initialization step as appropriate for your architecture.examples/hello/contracts/Universal.sol (1)
4-18: ---The
onlyGatewaymodifier must be defined locally in the Universal contract.The contract uses the
onlyGatewaymodifier on line 14 (theonCallfunction), but neither theUniversalcontract nor its parentUniversalContractinterface define this modifier. The UniversalContract interface does not provide an onlyGateway modifier — example contracts define onlyGateway themselves.Add the missing modifier definition to the Universal contract:
modifier onlyGateway() { require(msg.sender == gateway, "Only gateway"); _; }Adjust the gateway address reference as appropriate for your implementation (this may require storing the gateway address as a state variable or reading it from elsewhere in the UniversalContract interface).
🧹 Nitpick comments (3)
examples/nft/scripts/localnet.sh (1)
23-30: Standardize jq key notation for consistency.The environment variable lookups mix two jq syntax styles:
."key"(lines 23–25, 27, 29–30) and.["key"](lines 26, 28). While both are functionally equivalent, the inconsistency degrades readability. Standardize all lookups to use a single convention (e.g.,.["key"]for explicit bracket notation with quoted keys).Apply this diff to standardize to bracket notation:
-ZRC20_BNB=$(jq -r '."98".zrc20Tokens[] | select(.coinType == "gas" and .originChainId == "98") | .address' ~/.zetachain/localnet/registry.json) && echo $ZRC20_BNB -ZRC20_ETHEREUM=$(jq -r '."11155112".zrc20Tokens[] | select(.coinType == "gas" and .originChainId == "11155112") | .address' ~/.zetachain/localnet/registry.json) && echo $ZRC20_ETHEREUM -USDC_ETHEREUM=$(jq -r '."11155112".zrc20Tokens[] | select(.symbol == "USDC.ETH") | .address' ~/.zetachain/localnet/registry.json) && echo $USDC_ETHEREUM -GATEWAY_BNB=$(jq -r '."98".contracts[] | select(.contractType == "gateway") | .address' ~/.zetachain/localnet/registry.json) && echo $GATEWAY_BNB -UNISWAP_ROUTER=$(jq -r '."31337".contracts[] | select(.contractType == "uniswapV2Router02") | .address' ~/.zetachain/localnet/registry.json) && echo $UNISWAP_ROUTER -WZETA=$(jq -r '."31337".contracts[] | select(.contractType == "zetaToken") | .address' ~/.zetachain/localnet/registry.json) && echo $WZETA +ZRC20_BNB=$(jq -r '.["98"].zrc20Tokens[] | select(.coinType == "gas" and .originChainId == "98") | .address' ~/.zetachain/localnet/registry.json) && echo $ZRC20_BNB +ZRC20_ETHEREUM=$(jq -r '.["11155112"].zrc20Tokens[] | select(.coinType == "gas" and .originChainId == "11155112") | .address' ~/.zetachain/localnet/registry.json) && echo $ZRC20_ETHEREUM +USDC_ETHEREUM=$(jq -r '.["11155112"].zrc20Tokens[] | select(.symbol == "USDC.ETH") | .address' ~/.zetachain/localnet/registry.json) && echo $USDC_ETHEREUM +GATEWAY_BNB=$(jq -r '.["98"].contracts[] | select(.contractType == "gateway") | .address' ~/.zetachain/localnet/registry.json) && echo $GATEWAY_BNB +UNISWAP_ROUTER=$(jq -r '.["31337"].contracts[] | select(.contractType == "uniswapV2Router02") | .address' ~/.zetachain/localnet/registry.json) && echo $UNISWAP_ROUTER +WZETA=$(jq -r '.["31337"].contracts[] | select(.contractType == "zetaToken") | .address' ~/.zetachain/localnet/registry.json) && echo $WZETAexamples/nft/contracts/ZetaChainUniversalNFT.sol (1)
34-48: Consider validating the gas parameter.The
gasparameter is accepted without validation. IfUniversalNFTCoredoes not validate it internally, a value of zero or an excessively large value could lead to failed cross-chain operations or unexpected behavior.Consider adding validation:
function initialize( address initialOwner, string memory name, string memory symbol, uint256 gas // Set gas limit for universal NFT calls ) public initializer { + if (gas == 0) revert InvalidGasLimit(); __ERC721_init(name, symbol); __ERC721Enumerable_init(); __ERC721URIStorage_init(); __ERC721Pausable_init(); __Ownable_init(initialOwner); __ERC721Burnable_init(); __UUPSUpgradeable_init(); __UniversalNFTCore_init(gas); // Initialize universal NFT core }Note: If
UniversalNFTCorealready performs this validation, this suggestion can be disregarded.examples/swap/contracts/Swap.sol (1)
42-51: Add validation for initialize parameters.The
initializefunction acceptsuniswapRouterAddressandgasLimitAmountwithout validation. Zero values could cause transaction failures or unexpected behavior in swap operations.Consider adding validation:
function initialize( address uniswapRouterAddress, uint256 gasLimitAmount, address owner ) external initializer { + if (uniswapRouterAddress == address(0)) revert InvalidAddress(); + if (gasLimitAmount == 0) revert InvalidGasLimit(); __UUPSUpgradeable_init(); __Ownable_init(owner); uniswapRouter = uniswapRouterAddress; gasLimit = gasLimitAmount; }Note: You may need to add an
InvalidGasLimiterror declaration if not already present.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
- examples/call/yarn.lockis excluded by- !**/yarn.lock,- !**/*.lock
- examples/hello/yarn.lockis excluded by- !**/yarn.lock,- !**/*.lock
- examples/messaging/yarn.lockis excluded by- !**/yarn.lock,- !**/*.lock
- examples/nft/yarn.lockis excluded by- !**/yarn.lock,- !**/*.lock
- examples/swap/yarn.lockis excluded by- !**/yarn.lock,- !**/*.lock
- examples/token/yarn.lockis excluded by- !**/yarn.lock,- !**/*.lock
📒 Files selected for processing (33)
- examples/call/contracts/Connected.sol(0 hunks)
- examples/call/contracts/Universal.sol(0 hunks)
- examples/call/foundry.toml(0 hunks)
- examples/call/hardhat.config.ts(1 hunks)
- examples/call/package.json(2 hunks)
- examples/call/scripts/localnet.sh(2 hunks)
- examples/call/test/CallTest.t.sol(1 hunks)
- examples/hello/contracts/Universal.sol(1 hunks)
- examples/hello/foundry.toml(0 hunks)
- examples/hello/package.json(1 hunks)
- examples/hello/scripts/localnet.sh(1 hunks)
- examples/hello/test/Universal.t.sol(1 hunks)
- examples/messaging/package.json(1 hunks)
- examples/nft/contracts/EVMUniversalNFT.sol(1 hunks)
- examples/nft/contracts/ZetaChainUniversalNFT.sol(2 hunks)
- examples/nft/foundry.toml(0 hunks)
- examples/nft/hardhat.config.ts(1 hunks)
- examples/nft/package.json(1 hunks)
- examples/nft/scripts/localnet.sh(2 hunks)
- examples/nft/test/UniversalNFTTest.t.sol(3 hunks)
- examples/swap/commands/deploy.ts(1 hunks)
- examples/swap/contracts/Swap.sol(2 hunks)
- examples/swap/foundry.toml(1 hunks)
- examples/swap/package.json(1 hunks)
- examples/swap/scripts/localnet.sh(1 hunks)
- examples/swap/test/SwapTest.t.sol(0 hunks)
- examples/token/contracts/EVMUniversalToken.sol(1 hunks)
- examples/token/contracts/ZetaChainUniversalToken.sol(1 hunks)
- examples/token/foundry.toml(0 hunks)
- examples/token/hardhat.config.ts(1 hunks)
- examples/token/package.json(1 hunks)
- examples/token/scripts/localnet.sh(2 hunks)
- examples/token/test/UniversalTokenTest.t.sol(6 hunks)
💤 Files with no reviewable changes (7)
- examples/nft/foundry.toml
- examples/swap/test/SwapTest.t.sol
- examples/token/foundry.toml
- examples/hello/foundry.toml
- examples/call/contracts/Universal.sol
- examples/call/foundry.toml
- examples/call/contracts/Connected.sol
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-18T17:59:04.889Z
Learnt from: hernan-clich
PR: zeta-chain/example-contracts#280
File: examples/hello/frontend/src/utils/ethersHelpers.ts:1-6
Timestamp: 2025-09-18T17:59:04.889Z
Learning: Commit 1c6cffd3d29499bf0544987a9116c7c6571ff895 in zeta-chain/example-contracts resolves the noble/hashes esbuild build failure by adding resolutions for "noble/hashes": "1.8.0" and "noble/curves": "1.9.7" to examples/hello/frontend/package.json.
Applied to files:
- examples/nft/package.json
- examples/token/package.json
- examples/hello/package.json
📚 Learning: 2025-09-18T18:00:10.177Z
Learnt from: hernan-clich
PR: zeta-chain/example-contracts#280
File: examples/hello/frontend/src/ConnectedContent.tsx:3-10
Timestamp: 2025-09-18T18:00:10.177Z
Learning: Commit 1c6cffd3d29499bf0544987a9116c7c6571ff895 in zeta-chain/example-contracts#280 successfully resolved the noble/hashes "anumber" export error by adding resolutions in examples/hello/frontend/package.json to pin noble/hashes to 1.8.0 and noble/curves to 1.9.7, eliminating the version conflicts that were causing esbuild build failures.
Applied to files:
- examples/nft/package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: slither (examples/swap, swap.sarif)
- GitHub Check: slither (examples/call, call.sarif)
- GitHub Check: slither (examples/hello, hello.sarif)
🔇 Additional comments (29)
examples/hello/scripts/localnet.sh (1)
3-3: Shell option consolidation is syntactically sound and maintains semantic equivalence.The change combines three separate shell option commands into a single
set -exo pipefailinvocation, which is valid bash syntax and produces identical behavior: exit on error (-e), print commands (-x), and pipeline failure propagation (-o pipefail). This aligns well with the PR's simplification objectives.examples/token/scripts/localnet.sh (4)
3-3: Shell options consolidation follows best practices.Combining shell options into
set -exo pipefailis more concise and maintains proper error handling with pipe failure propagation.
25-31: Registry lookups are well-structured.The new environment variable extractions for USDC_ETHEREUM, GATEWAY_ETHEREUM, GATEWAY_ZETACHAIN, and WZETA follow consistent jq patterns and correctly target the appropriate chain identifiers (11155112 for Sepolia, 31337 for localnet).
40-40: Verify JSON extraction field consistency across deployment commands.Line 47 extracts
.deployedTo, while lines 40, 54, and 62 extract.contractAddress. This discrepancy suggests either different deployment tool versions or output schemas. Confirm that all extraction paths are correct for the current tool version and that they return the expected contract addresses.Also applies to: 47-47, 54-54, 62-62
49-55: Verify gateway parameter necessity given PR objectives.The deployment commands on lines 53 and 61 still pass
--gatewayparameters (--gateway "$GATEWAY_ETHEREUM"and--gateway "$GATEWAY_BNB"), despite the PR objectives stating that gateway addresses are now "fetched automatically from the registry." Clarify whether:
- These parameters are intentionally retained because the deployment tool (as opposed to the contract) requires them for target chain specification, or
- These parameters should be removed to align with the stated refactor goals.
Additionally, verify that the ZetaChainUniversalToken deployment (lines 36–40) has correctly removed any gateway or router parameters as intended by this PR.
Also applies to: 57-63
examples/token/hardhat.config.ts (1)
18-18: LGTM: Cancun EVM version targeting added.The explicit
evmVersion: "cancun"setting aligns with the broader PR objective to standardize EVM targeting across examples. This configuration, combined with optimizer and IR settings, ensures production-grade compilation.examples/nft/hardhat.config.ts (1)
18-18: LGTM: Cancun EVM version targeting added.The configuration mirrors the token example and correctly targets the Cancun EVM version with appropriate optimizer settings.
examples/call/hardhat.config.ts (1)
11-16: Verify structural inconsistency with other example configurations.The claim is verified:
examples/call/hardhat.config.tsuses a flat configuration structure withsettingsandversiondirectly undersolidity, whereas bothexamples/token/hardhat.config.tsandexamples/nft/hardhat.config.tsemploy thecompilersarray format. The call example is missing the optimizer configuration (enabled: true, runs: 1000) andviaIR: truesetting present in both token and nft examples. These omissions will result in suboptimal contract bytecode size and reduced gas efficiency.Determine whether this structural deviation is intentional for the call example or should be aligned with the token and nft examples. If alignment is required, apply the proposed diff to adopt the production-grade configuration.
examples/messaging/package.json (1)
62-66: Dependency updates align with PR objectives.The version bumps to @ZetaChain packages (standard-contracts ^4.1.0, toolkit ^16.2.2, zetachain ^7.2.0) are consistent with the broader refactoring to use UniversalContract.sol.
examples/swap/package.json (2)
60-62: Dependency updates support the UniversalContract refactoring.The protocol-contracts upgrade to 14.1.0-rc1 and toolkit to ^16.2.2 align with the broader changes to consolidate gateway access control through UniversalContract.
60-62: The original review comment is based on an incorrect assumption and should be disregarded.Swap.sol imports UniversalContract directly from
@zetachain/protocol-contracts/contracts/zevm/interfaces/UniversalContract.sol(line 12), not from standard-contracts. The required dependency—protocol-contracts—is already present in the swap example's package.json. While other examples (messaging, nft, token) depend on standard-contracts, the swap example's omission of that package is architecturally correct and intentional, as it imports the interface from protocol-contracts instead.Likely an incorrect or invalid review comment.
examples/swap/foundry.toml (1)
12-13: Configuration updates align with dependency changes.The updated remappings correctly point to the new versions of @zetachain/protocol-contracts and @zetachain/toolkit in node_modules. The removal of the EVM version constraint (as noted in the summary) allows the contracts to compile with the default/latest EVM version, which is appropriate for the UniversalContract refactoring.
examples/hello/package.json (1)
58-60: Dependency updates are consistent across examples.The version bumps match the coordinated upgrade across all examples, supporting the migration to UniversalContract-based initialization and removing gateway parameters.
examples/call/package.json (1)
31-31: Dependency updates align with UniversalContract migration.The version bumps are consistent with other examples. Note that @zetachain/toolkit is placed in devDependencies here (line 31) while other examples have it in dependencies, which may be intentional based on this example's usage patterns.
Also applies to: 61-65
examples/nft/package.json (1)
59-64: Comprehensive dependency updates support the refactoring.All four Zetachain packages are updated consistently. Notable: @zetachain/standard-contracts moved from release candidate (4.0.0-rc9) to stable (4.1.0), indicating production readiness of the UniversalContract abstraction.
examples/token/package.json (1)
60-64: Dependency updates mirror NFT example pattern.The version bumps are identical to the NFT example, with @zetachain/standard-contracts reaching stable 4.1.0. This consistency across examples ensures uniform behavior with the new UniversalContract pattern.
examples/swap/commands/deploy.ts (1)
23-26: Gateway parameter successfully removed from initialization.The initialize call now correctly excludes the gateway address, aligning with the PR's objective to use UniversalContract's built-in permission logic. The remaining parameters (uniswapRouter, gasLimit, owner) are properly ordered.
examples/call/scripts/localnet.sh (2)
3-3: LGTM: Shell options consolidated.Consolidating shell options into a single
set -exo pipefailcommand improves readability and follows standard bash best practices.
21-25: LGTM: Universal deployment simplified.The Universal contract deployment correctly reflects the parameterless constructor, aligning with the PR's objective to remove explicit gateway parameters.
examples/call/test/CallTest.t.sol (1)
24-24: LGTM: Universal instantiation updated correctly.The parameterless Universal constructor invocation aligns with the refactored Universal.sol that no longer requires explicit gateway initialization.
examples/token/contracts/ZetaChainUniversalToken.sol (1)
33-45: LGTM: Initialization simplified for ZetaChain deployment.The removal of
gatewayAddressanduniswapRouterAddressparameters, with core initialization now requiring onlygas, aligns with the PR's objective to eliminate explicit gateway parameters and fetch addresses automatically from the registry.examples/nft/contracts/EVMUniversalNFT.sol (1)
34-48: Verify parameter order consistency.Similar to
EVMUniversalToken, theinitializesignature has reordered parameters. Ensure that the__UniversalNFTCore_initcall on Line 48 matches the expected parameter order in the core contract.examples/token/test/UniversalTokenTest.t.sol (1)
16-69: LGTM: Test setup updated for new initialization signatures.The test correctly reflects the updated
initializesignatures for bothZetaChainUniversalToken(gas-only) andEVMUniversalToken(reordered parameters), ensuring test coverage aligns with the refactored contracts.examples/swap/scripts/localnet.sh (1)
3-3: LGTM: Shell options consolidated.Consolidating shell options into a single
set -exo pipefailcommand follows bash best practices and improves script readability.examples/hello/test/Universal.t.sol (1)
14-14: LGTM: Universal instantiation simplified.The parameterless constructor invocation correctly reflects the refactored Universal contract that no longer requires explicit gateway initialization.
examples/token/contracts/EVMUniversalToken.sol (1)
28-41: Verify that the parameter order in the__UniversalTokenCore_initcall matches the external contract's expected signature.Parameter order discrepancy detected: the
initializefunction signature declares parameters as(address initialOwner, string memory name, string memory symbol, uint256 gas, address payable gatewayAddress), but line 40 calls__UniversalTokenCore_init(gatewayAddress, address(this), gas)with a different parameter sequence. Confirm the actual function signature in@zetachain/standard-contractsv4.1.0's EVMUniversalTokenCorecontract to ensure the call parameters are passed in the correct order.examples/nft/test/UniversalNFTTest.t.sol (1)
21-57: Test initialization updates are consistent with contract changes.The test setup correctly reflects the new initialize signatures:
ZetaChainUniversalNFT.initializenow accepts 4 parameters (removed gateway/router addresses, added gas)
EVMUniversalNFT.initializeaccepts 5 parameters (gas added, gateway retained as last parameter)The gas value of 500000 is used consistently and appears reasonable for cross-chain operations.
examples/swap/contracts/Swap.sol (2)
247-271: onRevert function also relies on UniversalContract.The
onRevertfunction (line 247) uses theonlyGatewaymodifier and references thegatewayvariable (line 259), consistent with the pattern inonCallandwithdraw. The same verification comments above apply here.
62-67: No changes required to theonCallfunction signature.The
onlyGatewaymodifier is part of ZetaChain's UniversalContract interface and restricts execution so only the Gateway contract can invoke the function. The Swap.sol implementation correctly inherits from UniversalContract (imported from@zetachain/protocol-contracts), and the function signature at lines 62–67 properly applies both theoverridekeyword and theonlyGatewaymodifier. This pattern is consistent across multiple contracts in the codebase (e.g., examples/hello/contracts/Universal.sol, examples/call/contracts/Universal.sol) and aligns with ZetaChain's cross-chain execution model.
| GATEWAY_ZETACHAIN=$(jq -r '."31337".contracts[] | select(.contractType == "gateway") | .address' ~/.zetachain/localnet/registry.json) && echo $GATEWAY_ZETACHAIN | ||
| GATEWAY_ETHEREUM=$(jq -r '."11155112".contracts[] | select(.contractType == "gateway") | .address' ~/.zetachain/localnet/registry.json) && echo $GATEWAY_ETHEREUM | ||
| ZRC20_ETHEREUM=$(jq -r '."11155112".zrc20Tokens[] | select(.coinType == "gas" and .originChainId == "11155112") | .address' ~/.zetachain/localnet/registry.json) && echo $ZRC20_ETHEREUM | ||
| USDC_ETHEREUM=$(jq -r '."11155112".zrc20Tokens[] | select(.symbol == "USDC.ETH") | .address' ~/.zetachain/localnet/registry.json) && echo $USDC_ETHEREUM | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify that newly introduced variables are actively used.
The script now fetches USDC_ETHEREUM (line 25), GATEWAY_ZETACHAIN (line 28), and WZETA (line 30), but these variables are not visibly referenced in the provided script section. Confirm whether these are intended for external tool consumption, future expansion, or if they represent dead code that should be removed.
Run the following script to verify usage of these variables:
Also applies to: 28-28, 30-30
🏁 Script executed:
#!/bin/bash
# Description: Check if USDC_ETHEREUM, GATEWAY_ZETACHAIN, and WZETA are used anywhere in the script.
# Search for usages of the new variables
grep -n 'USDC_ETHEREUM\|GATEWAY_ZETACHAIN\|WZETA' examples/nft/scripts/localnet.sh | grep -v '^[0-9]*:[A-Z_]*=.*#\|^[0-9]*:[A-Z_]*=.*$'Length of output: 0
🏁 Script executed:
#!/bin/bash
# Display the entire localnet.sh file to inspect all variable usages
cat examples/nft/scripts/localnet.shLength of output: 6220
🏁 Script executed:
#!/bin/bash
# Search for all occurrences of the three variables with line numbers and context
echo "=== All occurrences of USDC_ETHEREUM ==="
grep -n "USDC_ETHEREUM" examples/nft/scripts/localnet.sh
echo "=== All occurrences of GATEWAY_ZETACHAIN ==="
grep -n "GATEWAY_ZETACHAIN" examples/nft/scripts/localnet.sh
echo "=== All occurrences of WZETA ==="
grep -n "WZETA" examples/nft/scripts/localnet.shLength of output: 582
Remove unused variable assignments at lines 25, 28, and 30.
The variables USDC_ETHEREUM, GATEWAY_ZETACHAIN, and WZETA are assigned and immediately echoed but never referenced in subsequent script operations. These represent dead code and should be removed. In contrast, actively used variables like ZRC20_ETHEREUM, GATEWAY_ETHEREUM, and GATEWAY_BNB appear in actual command invocations (e.g., cast send calls and deployment parameters), confirming this is genuine unused code rather than forward-looking declarations. Additionally, UNISWAP_ROUTER (line 29) follows the same unused pattern and should likewise be removed.
| @hernan-clich please, review. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
Tested deploying a Hello example contract and using in the example frontend, works perfectly fine.
        
          
                examples/call/package.json
              
                Outdated
          
        
      | "@solana/web3.js": "^1.95.8", | ||
| "@zetachain/networks": "13.0.0-rc1", | ||
| "@zetachain/protocol-contracts": "13.0.0", | ||
| "@zetachain/protocol-contracts": "14.1.0-rc1", | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use a stable release for these examples?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call! b37db41
| "@zetachain/protocol-contracts": "13.0.0", | ||
| "@zetachain/standard-contracts": "3.0.0", | ||
| "@zetachain/toolkit": "^16.0.0", | ||
| "@zetachain/standard-contracts": "^4.1.0", | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a typo? Other examples use v14.1.0 so I assume there's a 1 missing before the 4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are "standard" contracts, which are 4.1.0 (not protocol contracts, which are 14.1.0).
Imports
UniversalContract.sol.Advantages:
UniversalContract.solcontains everything a developer needs, and nothing they don’t.onlyGatewaymodifier needed: The permission logic is already built in.Depends on:
Related docs:
Summary by CodeRabbit