Skip to content
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

Ping Pong example #204

Closed
wants to merge 2 commits into from
Closed

Ping Pong example #204

wants to merge 2 commits into from

Conversation

fadeev
Copy link
Member

@fadeev fadeev commented Oct 16, 2024

npx hardhat localnet

yarn deploy

✅ Calling a contract directly works:

cast send 0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690 "pingPong(string)" 0x --value 10000000 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

❌ Making a call from ZetaChain fails:

npx hardhat hello-withdraw-and-call --contract 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E --receiver 0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690 --zrc20 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe --function "pingPong(string)" --amount 1 --network localhost --types '["string"]' hello

❌ Calling ZetaChain gateway directly also fails:

npx hardhat zetachain-call --function "pingPong(string)" --zrc20 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe --network localhost --receiver 0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690 --types '["string"]' hello

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Introduced a new pingPong function in the Echo contract, enabling interaction with a specified address and improving contract functionality.
    • Enhanced cross-chain call functionality in the Hello contract by integrating gas fee management and more complex interactions with the gateway.
  • Improvements
    • Added a console log statement for better visibility of the message variable in the helloWithdrawAndCall task.

@fadeev fadeev requested a review from andresaiello as a code owner October 16, 2024 06:27
Copy link

coderabbitai bot commented Oct 16, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes introduce a new event Foo and a new function pingPong to the Echo contract located in examples/hello/contracts/Echo.sol. The pingPong function is marked as external and payable, accepting an address parameter named receiver. It interacts with the GatewayEVM instance using a RevertOptions struct with default values. Additionally, the Hello contract has been modified to enhance its onCrossChainCall function, allowing for gas fee management and improved gateway interactions. A console log statement has also been added in the helloWithdrawAndCall.ts file for debugging purposes.

Changes

File Path Change Summary
examples/hello/contracts/Echo.sol Added event Foo(address) and method pingPong(address receiver) to the Echo contract.
examples/hello/contracts/Hello.sol Modified onCrossChainCall to decode message as an address, manage gas fees, and call gateway.
examples/hello/tasks/helloWithdrawAndCall.ts Added console log for message before calling withdrawAndCall.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant EchoContract as Echo
    participant GatewayEVM

    User->>Echo: call pingPong(receiver)
    Echo->>GatewayEVM: call(receiver, contractAddress, RevertOptions)
    GatewayEVM-->>Echo: response
    Echo-->>User: return response
Loading

Possibly related PRs

  • Added gateway call to examples #200: The gatewayCall function added in this PR is closely related to the pingPong function in the main PR, as both involve calling methods on a gateway with specified parameters, enhancing cross-chain interactions.
  • Call from EVM #201: The modifications to the Hello contract, particularly the addition of the withdrawAndCall function, relate to the pingPong function in the main PR, as both functions involve handling calls to a gateway and managing parameters for those calls.

Suggested reviewers

  • andresaiello

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@fadeev fadeev mentioned this pull request Oct 16, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Outside diff range and nitpick comments (1)
examples/hello/tasks/helloWithdrawAndCall.ts (1)

83-83: Consider enhancing the logging mechanism for improved debugging capabilities.

The addition of this console log statement provides valuable visibility into the constructed message before it's passed to the contract method, which can be instrumental for debugging purposes. However, to maintain code quality and adhere to best practices, consider the following recommendations:

  1. Implement a more robust logging mechanism that can be easily toggled between development and production environments. This approach allows for comprehensive debugging capabilities without compromising production code.

  2. Utilize a logging library such as Winston or Pino, which offer more advanced features like log levels, timestamps, and structured logging. This would provide a more scalable and maintainable solution for debugging across your application.

  3. If you decide to keep this log statement, ensure it's conditionally enabled only in non-production environments. This can be achieved by using environment variables or build flags.

Example implementation using environment variables:

if (process.env.NODE_ENV !== 'production') {
  console.log(`Debug - Message to be sent: ${message}`);
}

By implementing these suggestions, you can maintain the debugging benefits while ensuring your code remains production-ready and follows best practices for logging and error handling.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8bd1967 and f1c788a.

📒 Files selected for processing (3)
  • examples/hello/contracts/Echo.sol (2 hunks)
  • examples/hello/contracts/Hello.sol (1 hunks)
  • examples/hello/tasks/helloWithdrawAndCall.ts (1 hunks)
🧰 Additional context used

@@ -9,6 +9,7 @@ contract Echo {

event RevertEvent(string, RevertContext);
event HelloEvent(string, string);
event Foo(address);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Enhance event naming and documentation.

The event Foo lacks clarity and proper documentation. Consider the following improvements:

  1. Rename the event to a more descriptive name that reflects its purpose, e.g., ReceiverAddressLogged.
  2. Add a NatSpec comment to explain when and why this event is emitted.

Proposed changes:

-    event Foo(address);
+    /// @notice Emitted when a receiver address is logged
+    /// @param receiver The address of the receiver
+    event ReceiverAddressLogged(address indexed receiver);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
event Foo(address);
/// @notice Emitted when a receiver address is logged
/// @param receiver The address of the receiver
event ReceiverAddressLogged(address indexed receiver);

Comment on lines +34 to +46
function pingPong(address receiver) external payable {
gateway.call(
receiver,
abi.encode(address(this)),
RevertOptions({
revertAddress: address(0),
callOnRevert: false,
abortAddress: address(0),
revertMessage: "",
onRevertGasLimit: 0
})
);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Refactor function for clarity, completeness, and security.

The pingPong function requires several improvements:

  1. Rename the function to better describe its purpose, e.g., forwardCallToReceiver.
  2. Emit the Foo (or renamed) event to log the receiver address.
  3. Consider passing RevertOptions as a parameter instead of hardcoding default values.
  4. Implement checks for the payable amount if it's intended to be used.

Proposed refactoring:

-    function pingPong(address receiver) external payable {
+    /// @notice Forwards a call to a receiver address through the gateway
+    /// @param receiver The address to receive the call
+    /// @param revertOptions Options for handling reverts
+    function forwardCallToReceiver(address receiver, RevertOptions memory revertOptions) external payable {
+        require(msg.value > 0, "Forwarded value must be greater than 0");
+        emit ReceiverAddressLogged(receiver);
         gateway.call(
             receiver,
             abi.encode(address(this)),
-            RevertOptions({
-                revertAddress: address(0),
-                callOnRevert: false,
-                abortAddress: address(0),
-                revertMessage: "",
-                onRevertGasLimit: 0
-            })
+            revertOptions
         );
     }

This refactoring improves function naming, adds event emission, allows for flexible revert options, and includes a basic check for the payable amount.

Committable suggestion was skipped due to low confidence.

gateway.call(
abi.encodePacked(receiver),
zrc20,
abi.encodeWithSelector(0xc8580dfc, address(this)),
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Compute Function Selector Programmatically for Maintainability

Hardcoding the function selector 0xc8580dfc reduces code readability and can lead to errors if the function signature changes. It is advisable to compute the selector using Solidity's built-in functions to enhance maintainability and clarity.

Apply this diff to compute the function selector programmatically:

-            abi.encodeWithSelector(0xc8580dfc, address(this)),
+            abi.encodeWithSelector(bytes4(keccak256("pingPong(address)")), address(this)),

Alternatively, declare the function selector as a constant for better code organization:

bytes4 constant PINGPONG_SELECTOR = bytes4(keccak256("pingPong(address)"));

And use it in your call:

abi.encodeWithSelector(PINGPONG_SELECTOR, address(this)),

Comment on lines +30 to +32
// cast send 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe "transfer(address,uint256)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E 2000000000000000000 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
// cast send 0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690 "pingPong(address)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E --value 10000000 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
// cast call 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe "balanceOf(address)(uint256)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove Hardcoded Private Keys from Comments

Including private keys in code comments, even for testing purposes, poses a significant security risk and is considered a bad practice. It can lead to unintended exposure of sensitive information, especially if the code is shared publicly or moved to a production environment.

Please remove or obfuscate the private keys in the comments to prevent potential security vulnerabilities:

-        // cast send 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe "transfer(address,uint256)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E 2000000000000000000 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
-        // cast send 0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690 "pingPong(address)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E --value 10000000 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
+        // cast send [Contract Address] "transfer(address,uint256)" [Recipient Address] [Amount] --private-key [PRIVATE KEY]
+        // cast send [Contract Address] "pingPong(address)" [Recipient Address] --value [Value] --private-key [PRIVATE KEY]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// cast send 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe "transfer(address,uint256)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E 2000000000000000000 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
// cast send 0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690 "pingPong(address)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E --value 10000000 --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
// cast call 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe "balanceOf(address)(uint256)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E
// cast send [Contract Address] "transfer(address,uint256)" [Recipient Address] [Amount] --private-key [PRIVATE KEY]
// cast send [Contract Address] "pingPong(address)" [Recipient Address] --value [Value] --private-key [PRIVATE KEY]
// cast call 0x2ca7d64A7EFE2D62A725E2B35Cf7230D6677FfEe "balanceOf(address)(uint256)" 0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E

Comment on lines +26 to +28
address receiver = abi.decode(message, (address));
(, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(700000);
IZRC20(zrc20).approve(address(gateway), gasFee);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Parameterize the Gas Limit for Flexibility

Hardcoding the gas limit to 700,000 reduces the flexibility and adaptability of the contract. Consider defining the gas limit as a constant or allowing it to be passed as a parameter to enhance maintainability and ease future adjustments.

Apply this diff to define the gas limit as a constant:

+    uint256 constant GAS_LIMIT = 700_000;

     function onCrossChainCall(
         zContext calldata context,
         address zrc20,
         uint256 amount,
         bytes calldata message
     ) external override {
         address receiver = abi.decode(message, (address));
-        (, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(700000);
+        (, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(GAS_LIMIT);
         IZRC20(zrc20).approve(address(gateway), gasFee);

Committable suggestion was skipped due to low confidence.

@fadeev fadeev marked this pull request as draft October 16, 2024 15:49
@@ -30,6 +31,20 @@ contract Echo {
gateway.call(receiver, message, revertOptions);
}

function pingPong(address receiver) external payable {
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: instead of pingPong I guess should be ping because the pong it's on the other side

@fadeev fadeev closed this Nov 8, 2024
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.

2 participants