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

feat: add sender when calling connected chain contracts from zetachain #355

Merged
merged 17 commits into from
Sep 27, 2024

Conversation

skosito
Copy link
Contributor

@skosito skosito commented Sep 18, 2024

same as: #350 just correct base branch and onCall function payable

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced call execution with new functions for authenticated and arbitrary calls in GatewayEVM and GatewayZEVM contracts.
    • Introduction of CallOptions structure for standardized call parameters, improving clarity in function calls.
    • New onCall function in ReceiverEVM contract to handle incoming calls with context.
    • New event ReceivedOnCall added for better event handling in IReceiverEVMEvents.
  • Bug Fixes

    • Improved error handling and authorization checks in various contract functions.
  • Tests

    • Expanded test coverage for GatewayEVM and GatewayZEVM with new scenarios and validation checks.
    • Updated tests to utilize the new CallOptions structure for consistency.

Copy link
Contributor

coderabbitai bot commented Sep 18, 2024

Walkthrough

Walkthrough

This pull request introduces significant modifications to the GatewayEVM and GatewayZEVM contracts, focusing on the execution of calls with new structures for handling call options, including gas limits. The go.mod file reflects updates to various dependencies, including downgrades and the addition of new libraries. The changes enhance the functionality and clarity of the contracts, particularly in managing authenticated and arbitrary calls, while also improving the testing framework to cover new scenarios.

Changes

File Change Summary
go.mod Updated dependency versions, including downgrades and the addition of a new dependency.
v2/contracts/evm/GatewayEVM.sol Removed _execute function; added _executeAuthenticatedCall and _executeArbitraryCall. Overloaded execute function to support a MessageContext.
v2/contracts/evm/interfaces/IGatewayEVM.sol Added new error and methods; introduced MessageContext struct and Callable interface.
v2/contracts/zevm/GatewayZEVM.sol Introduced CallOptions struct for call parameters; added withdrawAndCall and call functions.
v2/contracts/zevm/interfaces/IGatewayZEVM.sol Updated events to use CallOptions; added new functions for withdrawals and calls.
v2/test/GatewayEVM.t.sol Added new test functions for gateway.execute scenarios, enhancing coverage for authorization checks.
v2/test/GatewayEVMZEVM.t.sol Updated imports and function calls to utilize CallOptions.
v2/test/GatewayZEVM.t.sol Modified tests to incorporate CallOptions in various withdrawal and call scenarios.
v2/test/utils/GatewayEVMUpgradeTest.sol Removed _execute; added new functions for authenticated and arbitrary calls.
v2/test/utils/IReceiverEVM.sol Added ReceivedOnCall event to the interface.
v2/test/utils/ReceiverEVM.sol Introduced onCall function to handle calls with MessageContext.

Possibly related issues

Possibly related PRs

Suggested reviewers

  • fadeev
  • CharlieMc0
  • brewmaster012
  • andresaiello
  • fbac
  • lumtis

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.

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.

@codecov-commenter
Copy link

codecov-commenter commented Sep 18, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 91.92%. Comparing base (c2ce913) to head (b98b0d9).
Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #355      +/-   ##
==========================================
+ Coverage   91.39%   91.92%   +0.52%     
==========================================
  Files           8        8              
  Lines         337      359      +22     
  Branches      110      117       +7     
==========================================
+ Hits          308      330      +22     
  Misses         29       29              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@skosito skosito changed the title Protocol integration auth call [draft] feat: add sender when calling connected chain contracts from zetachain Sep 24, 2024
@skosito skosito marked this pull request as ready for review September 24, 2024 15:56
@skosito skosito linked an issue Sep 24, 2024 that may be closed by this pull request
Copy link
Contributor

@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: 14

Outside diff range and nitpick comments (10)
go.mod (1)

Line range hint 1-26: Address the overall trend of dependency downgrades

There's a noticeable trend of downgrading multiple dependencies in this update. While each individual downgrade may have its reasons, this overall pattern raises some concerns:

  1. It may introduce technical debt by using older versions of libraries.
  2. The project might miss out on important bug fixes, security updates, and performance improvements.
  3. It could make future upgrades more challenging as the gap between the used versions and the latest versions widens.

Consider the following recommendations:

  1. Document the specific reasons for each downgrade to maintain institutional knowledge.
  2. Create a plan for gradually updating these dependencies in the future to reduce technical debt.
  3. Implement a dependency management strategy that balances stability with staying up-to-date.
  4. Regularly review and test against newer versions of these dependencies to ensure easier future upgrades.
v2/test/utils/ReceiverEVM.sol (1)

76-85: LGTM: New onCall function added, with suggestions for improvement.

The onCall function is correctly implemented as an external payable function, matching the expected interface. However, consider the following suggestions:

  1. The function doesn't use its input parameters. Consider adding logic to process messageContext and message.
  2. There's no check or use of msg.value. If this is intentional for testing, consider adding a comment explaining this.
  3. The function returns bytes memory but doesn't return any data. Consider either removing the return type if not needed or returning some meaningful data.

Example improvement:

function onCall(
    MessageContext calldata messageContext,
    bytes calldata message
)
    external
    payable
    returns (bytes memory)
{
    // Process message context and message
    // For example, you could return the message as-is
    emit ReceivedOnCall(messageContext.sender, msg.value, message);
    return message;
}
v2/test/GatewayEVMZEVM.t.sol (2)

137-144: LGTM: Improved event emission with CallOptions struct

The update to the emit statement enhances code clarity by using a CallOptions struct. This change likely reflects modifications in the contract's event structure and improves maintainability.

Consider extracting the CallOptions struct creation to a separate variable for improved readability:

+CallOptions memory callOptions = CallOptions({ gasLimit: 1, isArbitraryCall: true });
 emit Called(
     address(ownerZEVM),
     address(zrc20),
     abi.encodePacked(receiverEVM),
     message,
-    CallOptions({ gasLimit: 1, isArbitraryCall: true }),
+    callOptions,
     revertOptions
 );

This change would make the emit statement cleaner and allow for easier reuse of the CallOptions if needed elsewhere in the test.


204-204: LGTM: Consistent use of CallOptions struct in withdrawAndCall

The changes in this function are consistent with the previous modifications, using the CallOptions struct in both the event emission and the gatewayZEVM.withdrawAndCall function call. This ensures consistency with the updated contract interface.

For consistency with the previous suggestion and to improve readability, consider extracting the CallOptions struct creation to a separate variable:

+CallOptions memory callOptions = CallOptions({ gasLimit: 1, isArbitraryCall: true });
 emit Withdrawn(
     ownerZEVM,
     0,
     abi.encodePacked(receiverEVM),
     address(zrc20),
     500_000,
     expectedGasFee,
     zrc20.PROTOCOL_FLAT_FEE(),
     message,
-    CallOptions({ gasLimit: 1, isArbitraryCall: true }),
+    callOptions,
     revertOptions
 );
 vm.prank(ownerZEVM);
 gatewayZEVM.withdrawAndCall(
     abi.encodePacked(receiverEVM),
     500_000,
     address(zrc20),
     message,
-    CallOptions({ gasLimit: 1, isArbitraryCall: true }),
+    callOptions,
     revertOptions
 );

This change would improve consistency and make the code more readable and maintainable.

Also applies to: 208-215

v2/contracts/zevm/interfaces/IGatewayZEVM.sol (2)

15-15: Typo in 'arbitrary' in documentation

The word "arbirtrary" is misspelled in multiple comments. It should be corrected to "arbitrary".

Apply the following diff to fix the typos:

-/// @param callOptions Call options including gas limit and arbirtrary call flag.
+/// @param callOptions Call options including gas limit and arbitrary call flag.

Also applies to: 35-35, 142-142, 174-174, 286-286


288-290: Consider enhancing the CallOptions struct documentation

To improve clarity, consider providing more detailed descriptions for the CallOptions struct fields.

Update the comments as follows:

 /// @notice CallOptions struct passed to call and withdrawAndCall functions.
 /// @param gasLimit Gas limit for the cross-chain call execution.
-/// @param isArbitraryCall Indicates if call should be arbitrary or authenticated.
+/// @param isArbitraryCall Indicates whether the call is arbitrary (true) or authenticated (false).
 struct CallOptions {
     uint256 gasLimit;
     bool isArbitraryCall;
 }
v2/contracts/evm/GatewayEVM.sol (1)

126-128: Redundant variable initialization

In the first execute function, the variable result is declared and then immediately assigned.

You can simplify the code by combining declaration and assignment:

-bytes memory result;
-result = _executeAuthenticatedCall(messageContext, destination, data);
+bytes memory result = _executeAuthenticatedCall(messageContext, destination, data);
v2/test/GatewayZEVM.t.sol (3)

76-76: Consider using a realistic gasLimit in callOptions.

In the setUp function, callOptions is initialized with gasLimit: 1. For more accurate testing, consider setting gasLimit to a value that reflects actual expected gas usage in real scenarios.


Line range hint 277-277: Correct the function name for clarity.

The function testWithdrawAndCallZETAFailsIfAmountIsReceiverIsZeroAddress has a naming issue. It should likely be renamed to testWithdrawAndCallZETAFailsIfReceiverIsZeroAddress to accurately describe the test case.


287-287: Rename function to reflect the test scenario accurately.

The function testWithdrawAndCallZETAWithCallOptsFailsIfAmountIsReceiverIsZeroAddress appears to have a typo. Consider renaming it to testWithdrawAndCallZETAWithCallOptsFailsIfReceiverIsZeroAddress for clarity.

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c2ce913 and b98b0d9.

Files ignored due to path filters (56)
  • go.sum is excluded by !**/*.sum
  • v2/pkg/erc20custody.sol/erc20custody.go is excluded by !v2/pkg/**
  • v2/pkg/erc20custody.t.sol/erc20custodytest.go is excluded by !v2/pkg/**
  • v2/pkg/erc20custodyechidnatest.sol/erc20custodyechidnatest.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayevm.sol/gatewayevm.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayevm.t.sol/gatewayevminboundtest.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayevm.t.sol/gatewayevmtest.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayevmechidnatest.sol/gatewayevmechidnatest.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayevmupgrade.t.sol/gatewayevmuupsupgradetest.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayevmupgradetest.sol/gatewayevmupgradetest.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayevmzevm.t.sol/gatewayevmzevmtest.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayzevm.sol/gatewayzevm.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayzevm.t.sol/gatewayzevminboundtest.go is excluded by !v2/pkg/**
  • v2/pkg/gatewayzevm.t.sol/gatewayzevmoutboundtest.go is excluded by !v2/pkg/**
  • v2/pkg/igatewayevm.sol/callable.go is excluded by !v2/pkg/**
  • v2/pkg/igatewayevm.sol/igatewayevm.go is excluded by !v2/pkg/**
  • v2/pkg/igatewayevm.sol/igatewayevmerrors.go is excluded by !v2/pkg/**
  • v2/pkg/igatewayzevm.sol/igatewayzevm.go is excluded by !v2/pkg/**
  • v2/pkg/igatewayzevm.sol/igatewayzevmevents.go is excluded by !v2/pkg/**
  • v2/pkg/ireceiverevm.sol/ireceiverevmevents.go is excluded by !v2/pkg/**
  • v2/pkg/receiverevm.sol/receiverevm.go is excluded by !v2/pkg/**
  • v2/pkg/senderzevm.sol/senderzevm.go is excluded by !v2/pkg/**
  • v2/pkg/zetaconnectornative.sol/zetaconnectornative.go is excluded by !v2/pkg/**
  • v2/pkg/zetaconnectornative.t.sol/zetaconnectornativetest.go is excluded by !v2/pkg/**
  • v2/pkg/zetaconnectornonnative.sol/zetaconnectornonnative.go is excluded by !v2/pkg/**
  • v2/pkg/zetaconnectornonnative.t.sol/zetaconnectornonnativetest.go is excluded by !v2/pkg/**
  • v2/pkg/zrc20.t.sol/zrc20test.go is excluded by !v2/pkg/**
  • v2/types/GatewayEVM.ts is excluded by !v2/types/**
  • v2/types/GatewayEVMEchidnaTest.ts is excluded by !v2/types/**
  • v2/types/GatewayEVMUpgradeTest.ts is excluded by !v2/types/**
  • v2/types/GatewayZEVM.ts is excluded by !v2/types/**
  • v2/types/IGatewayEVM.sol/Callable.ts is excluded by !v2/types/**
  • v2/types/IGatewayEVM.sol/IGatewayEVM.ts is excluded by !v2/types/**
  • v2/types/IGatewayEVM.sol/index.ts is excluded by !v2/types/**
  • v2/types/IGatewayZEVM.sol/IGatewayZEVM.ts is excluded by !v2/types/**
  • v2/types/IGatewayZEVM.sol/IGatewayZEVMEvents.ts is excluded by !v2/types/**
  • v2/types/IReceiverEVM.sol/IReceiverEVMEvents.ts is excluded by !v2/types/**
  • v2/types/ReceiverEVM.ts is excluded by !v2/types/**
  • v2/types/factories/ERC20CustodyEchidnaTest__factory.ts is excluded by !v2/types/**
  • v2/types/factories/ERC20Custody__factory.ts is excluded by !v2/types/**
  • v2/types/factories/GatewayEVMEchidnaTest__factory.ts is excluded by !v2/types/**
  • v2/types/factories/GatewayEVMUpgradeTest__factory.ts is excluded by !v2/types/**
  • v2/types/factories/GatewayEVM__factory.ts is excluded by !v2/types/**
  • v2/types/factories/GatewayZEVM__factory.ts is excluded by !v2/types/**
  • v2/types/factories/IGatewayEVM.sol/Callable__factory.ts is excluded by !v2/types/**
  • v2/types/factories/IGatewayEVM.sol/IGatewayEVMErrors__factory.ts is excluded by !v2/types/**
  • v2/types/factories/IGatewayEVM.sol/IGatewayEVM__factory.ts is excluded by !v2/types/**
  • v2/types/factories/IGatewayEVM.sol/index.ts is excluded by !v2/types/**
  • v2/types/factories/IGatewayZEVM.sol/IGatewayZEVMEvents__factory.ts is excluded by !v2/types/**
  • v2/types/factories/IGatewayZEVM.sol/IGatewayZEVM__factory.ts is excluded by !v2/types/**
  • v2/types/factories/IReceiverEVM.sol/IReceiverEVMEvents__factory.ts is excluded by !v2/types/**
  • v2/types/factories/ReceiverEVM__factory.ts is excluded by !v2/types/**
  • v2/types/factories/SenderZEVM__factory.ts is excluded by !v2/types/**
  • v2/types/factories/ZetaConnectorNative__factory.ts is excluded by !v2/types/**
  • v2/types/factories/ZetaConnectorNonNative__factory.ts is excluded by !v2/types/**
  • v2/types/index.ts is excluded by !v2/types/**
Files selected for processing (11)
  • go.mod (1 hunks)
  • v2/contracts/evm/GatewayEVM.sol (5 hunks)
  • v2/contracts/evm/interfaces/IGatewayEVM.sol (3 hunks)
  • v2/contracts/zevm/GatewayZEVM.sol (6 hunks)
  • v2/contracts/zevm/interfaces/IGatewayZEVM.sol (6 hunks)
  • v2/test/GatewayEVM.t.sol (4 hunks)
  • v2/test/GatewayEVMZEVM.t.sol (3 hunks)
  • v2/test/GatewayZEVM.t.sol (9 hunks)
  • v2/test/utils/GatewayEVMUpgradeTest.sol (4 hunks)
  • v2/test/utils/IReceiverEVM.sol (1 hunks)
  • v2/test/utils/ReceiverEVM.sol (2 hunks)
Additional comments not posted (26)
go.mod (6)

12-12: Confirm rationale for go-ole/go-ole downgrade

The github.com/go-ole/go-ole package has been downgraded from v1.3.0 to v1.2.5. While this is a minor version downgrade, it may remove bug fixes or small features introduced in later 1.2.x or 1.3.0 versions.

Please confirm:

  1. The reason for this specific downgrade.
  2. That any bug fixes or features introduced in versions 1.2.6 to 1.3.0 are not critical for your use case.
  3. This change doesn't introduce any compatibility issues with other dependencies or parts of the system.

16-16: Confirm rationale for holiman/uint256 downgrade

The github.com/holiman/uint256 package has been downgraded from v1.2.4 to v1.2.3. While this is a patch version downgrade and unlikely to introduce breaking changes, it may remove bug fixes or optimizations introduced in v1.2.4.

Please confirm:

  1. The specific reason for downgrading to v1.2.3.
  2. That any bug fixes or optimizations introduced in v1.2.4 are not critical for your use case.
  3. This change aligns with the project's dependency management strategy.

23-23: Verify rationale for golang.org/x/sys downgrade

The golang.org/x/sys package has been downgraded from v0.16.0 to v0.15.0. While this is a minor version downgrade, it may remove features or optimizations introduced in v0.16.0.

Please confirm:

  1. The specific reason for downgrading to v0.15.0.
  2. That this downgrade is compatible with the Go version used in the project.
  3. That any features or optimizations introduced in v0.16.0 are not critical for your use case.
  4. This change doesn't introduce any compatibility issues with other dependencies or parts of the system.

10-10: Verify compatibility with downgraded golang-set version

The github.com/deckarep/golang-set package has been downgraded from v2.1.0 to v1.8.0. This is a major version change that could potentially break existing code relying on v2 features.

Please ensure that:

  1. The codebase has been updated to use the v1 API of golang-set.
  2. There are no remaining references to v2-specific features or syntax.
  3. This downgrade doesn't introduce any compatibility issues with other parts of the system.

To help verify the impact, you can run the following script:

#!/bin/bash
# Description: Check for usage of golang-set v2 features

# Test: Search for potential usage of v2 APIs
rg --type go "mapset\.New\w*Set"

17-17: Clarify the purpose of adding rjeczalik/notify

A new dependency, github.com/rjeczalik/notify v0.9.1, has been added to the project.

Please provide information on:

  1. The specific use case or functionality that requires this new dependency.
  2. Any potential impact on the project's performance or complexity.
  3. Whether this addition aligns with the project's overall architecture and design principles.

To help understand the usage, you can run the following script:

#!/bin/bash
# Description: Check for usage of rjeczalik/notify in the codebase

# Test: Search for import and usage of notify package
rg --type go "github.com/rjeczalik/notify"

5-5: Verify the rationale for downgrading ethereum/go-ethereum

The ethereum/go-ethereum package has been significantly downgraded from v1.13.15 to v1.10.26. This is a major version change that could potentially introduce compatibility issues or remove features that the project might be relying on.

Please provide the rationale for this downgrade and confirm that:

  1. The project doesn't rely on any features introduced in versions 1.11-1.13.
  2. This change doesn't introduce any compatibility issues with other dependencies or parts of the system.
  3. The team is aware of any security fixes or important updates that might be missed by using this older version.

To help verify the impact, you can run the following script:

v2/test/utils/IReceiverEVM.sol (1)

39-40: New event ReceivedOnCall() added: Consider adding documentation

The addition of the ReceivedOnCall() event is noted. This event appears to signal when a call is received, which aligns with the purpose of the interface. However, to maintain consistency with other events in this interface, consider adding a documentation comment explaining its purpose and when it's emitted.

Consider adding a documentation comment for the new event, similar to the existing ones:

+    /// @notice Emitted when a call is received.
     event ReceivedOnCall();

Also, verify if any implementations of this interface need to be updated to emit this new event where appropriate.

Verification successful

Verified: ReceivedOnCall() event added with appropriate documentation

The ReceivedOnCall() event has been successfully added without affecting existing implementations, as no contracts currently implement IReceiverEVMEvents. Ensure that future implementations of this interface emit the ReceivedOnCall() event as appropriate.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for implementations of IReceiverEVMEvents and verify if they need updates

# Search for files implementing IReceiverEVMEvents
echo "Files potentially implementing IReceiverEVMEvents:"
rg --type solidity -l "contract.*implements.*IReceiverEVMEvents"

# Search for existing emit statements of ReceivedOnCall
echo "\nExisting emit statements of ReceivedOnCall:"
rg --type solidity "emit ReceivedOnCall()"

Length of output: 389


Script:

#!/bin/bash
# Description: Corrected script to check for implementations of IReceiverEVMEvents and verify if they need updates

# Search for files implementing IReceiverEVMEvents
echo "Files potentially implementing IReceiverEVMEvents:"
rg "contract.*implements.*IReceiverEVMEvents" --glob "*.sol" -l

# Search for existing emit statements of ReceivedOnCall
echo "\nExisting emit statements of ReceivedOnCall:"
rg "emit ReceivedOnCall()" --glob "*.sol"

Length of output: 438

v2/test/utils/ReceiverEVM.sol (1)

5-5: LGTM: New import statement is correctly added.

The import of MessageContext is necessary for the new onCall function and is correctly placed.

v2/test/GatewayEVMZEVM.t.sol (2)

16-16: LGTM: Import statements improved

The changes to the import statements enhance code organization and readability:

  1. Using named import for SystemContractMock (line 16) clarifies which specific component is being imported.
  2. Consolidating related imports (line 20) reduces the number of import statements and groups related components together.

These modifications align with best practices for managing imports in Solidity.

Also applies to: 20-20


Line range hint 1-268: Overall assessment: Consistent and well-implemented changes

The modifications in this test file are consistent and well-implemented throughout. The main changes include:

  1. Improved import statements for better code organization.
  2. Introduction of the CallOptions struct in relevant function calls and event emissions.

These changes likely reflect updates in the contract interfaces and improve the overall readability and maintainability of the test code. The uniform application of the CallOptions struct ensures consistency across different test functions.

To further enhance the code:

  1. Consider implementing the suggested extractions of CallOptions struct creation to separate variables for improved readability.
  2. Ensure that the changes in this test file accurately reflect the modifications made in the actual contract implementations.
  3. Verify that all test cases still pass with these modifications and consider adding new test cases if the contract behavior has been extended.
v2/contracts/evm/interfaces/IGatewayEVM.sol (4)

85-85: Approved: Added new error NotAllowedToCallOnCall()

The new error definition is appropriate and follows the existing naming conventions in IGatewayEVMErrors.


117-130: Approved: Added overloaded execute function with MessageContext

The addition of the overloaded execute function enhances functionality by allowing calls with sender context. The function signature and modifiers are appropriate.


193-197: Approved: Added MessageContext struct

The incorporation of the MessageContext struct improves the ability to pass sender information through function calls. The struct is properly defined.


200-202: Approved: Added Callable interface with onCall function

The introduction of the Callable interface standardizes the onCall function implementation for contracts receiving authenticated calls. The function signature is clear and adheres to best practices.

v2/contracts/zevm/interfaces/IGatewayZEVM.sol (2)

137-152: Ensure function overloading works as intended

The addition of overloaded withdrawAndCall functions introduces new function signatures. Ensure that overloading does not cause ambiguity and that all calls resolve to the correct function.

Confirm that:

  • The Solidity compiler version used supports function overloading as intended.
  • The function signatures are unique and do not conflict with existing functions.
  • Documentation is updated to clearly differentiate between the overloaded functions.

Also applies to: 169-184


186-199: Verify the new call function integration

The new call function allows calling contracts on external chains without asset transfer. Ensure that:

Run the following script to verify that there are no naming conflicts and that the function is properly declared:

Verification successful

✅ Verified: No naming conflicts found with the call function integration.

  • The call function is properly declared in IGatewayZEVM.sol without conflicting with other call functions in different contracts.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any function naming conflicts with `call`.

# Test: Search for `function call(` declarations. Expect: No conflicts.
ast-grep --lang solidity --pattern $'function call($_, $_, $_, $_, $_)$_' --ignore "v2/contracts/zevm/interfaces/IGatewayZEVM.sol"

Length of output: 246


Script:

#!/bin/bash
# Description: Check for any function naming conflicts with `call` in Solidity files, excluding IGatewayZEVM.sol.

# Search for `function call(` declarations in Solidity files.
rg 'function\s+call\s*\(' --type solidity --glob '!v2/contracts/zevm/interfaces/IGatewayZEVM.sol'

Length of output: 132


Script:

#!/bin/bash
# Description: Check for any function naming conflicts with `call` in Solidity files, excluding IGatewayZEVM.sol.

# Search for `function call(` declarations in Solidity files, excluding the specified interface file.
rg 'function\s+call\s*\(' -g '*.sol' -g '!v2/contracts/zevm/interfaces/IGatewayZEVM.sol'

Length of output: 458

v2/contracts/evm/GatewayEVM.sol (4)

Line range hint 107-132: Addition of execute function with MessageContext parameter

The introduction of the new execute function that accepts a MessageContext and calls _executeAuthenticatedCall enhances the contract's ability to handle authenticated calls. The use of nonReentrant, onlyRole(TSS_ROLE), and whenNotPaused modifiers ensures security and proper access control.


134-153: Overloading of execute function for arbitrary calls

The added overload of the execute function allows for arbitrary calls without authentication. It correctly calls _executeArbitraryCall and emits the Executed event upon success.


149-153: Verify access control for the overloaded execute function

Ensure that the onlyRole(TSS_ROLE) modifier sufficiently restricts access to the execute function to prevent unauthorized usage.

Please confirm that only the intended entities have the TSS_ROLE assigned.

Verification successful

Adjusting the verification script to correctly target Solidity files.


Access control for the execute function is properly restricted by the onlyRole(TSS_ROLE) modifier.

  • The TSS_ROLE is assigned exclusively to tssAddress_ in the following files:
    • v2/test/utils/GatewayEVMUpgradeTest.sol
    • v2/contracts/evm/GatewayEVM.sol
    • v2/contracts/evm/ZetaConnectorBase.sol
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify entities with TSS_ROLE.

# Test: List all assignments of TSS_ROLE.
rg --type solidity -A 3 $'_grantRole(TSS_ROLE, $_);'

Length of output: 86


Script:

#!/bin/bash
# Description: Verify entities with TSS_ROLE by searching .sol files.

# Test: List all assignments of TSS_ROLE in Solidity files.
rg '_grantRole\(TSS_ROLE,\s*[^)]+\);' --glob '*.sol'

Length of output: 294


408-414: Ensure safe execution in _executeArbitraryCall

While _executeArbitraryCall effectively calls the destination with provided data, it's important to consider the impact of allowing arbitrary external calls. Ensure that there are no security vulnerabilities introduced by this function, such as reentrancy attacks or unauthorized access.

Please run the following script to check for potential reentrancy vulnerabilities:

v2/contracts/zevm/GatewayZEVM.sol (1)

4-4: Approved: Import statement correctly includes CallOptions and IGatewayZEVM

The import statement correctly brings in CallOptions and IGatewayZEVM from the specified file, which are necessary for the new functionality.

v2/test/GatewayEVM.t.sol (3)

223-229: Confirm zero address handling in execute with MessageContext

The test testExecuteWithMsgContextFailsIfDestinationIsZeroAddress correctly verifies that calling gateway.execute with a zero destination address and a MessageContext reverts with a ZeroAddress error. Ensure that the contract's execute function implements this check appropriately.

You can verify the presence of the zero address check with the following script:


140-147: Verify the correctness of the sender address in MessageContext

In this test function testForwardCallToReceiveOnCallUsingAuthCall, you are invoking gateway.execute with a MessageContext where the sender is set to address(0x123). Please verify that address(0x123) is the intended sender for this test case and that it aligns with the expected behavior of the execute function when using authenticated calls.

You can confirm the intended usage with the following script:

Verification successful

Verified: Correctness of sender address in MessageContext

The sender address address(0x123) in the MessageContext is correctly set and aligns with the intended behavior of the execute function for this test case.

  • File: v2/test/GatewayEVM.t.sol
  • Function: testForwardCallToReceiveOnCallUsingAuthCall
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Ensure that the sender address in MessageContext is correctly used in gateway.execute calls.

# Search for all instances where gateway.execute is called with MessageContext
rg 'gateway\.execute\(\s*MessageContext\(\{\s*sender\s*:\s*address\(0x[0-9a-fA-F]+\)\s*\}\),'

# Expected Result: Verify that the sender address used here matches the intended test scenarios.

Length of output: 287


Script:

#!/bin/bash
# Description: Search for gateway.execute calls with MessageContext and extract sender addresses.

# Search for all instances where gateway.execute is called with MessageContext and extract the sender addresses
rg 'gateway\.execute\(\s*MessageContext\s*\(\s*\{\s*sender\s*:\s*address\(0x[0-9a-fA-F]+\)\s*\}\s*\)\s*,\s*address\([^)]+\)\s*,\s*bytes\([^)]+\)\s*\)'

Length of output: 277


162-173: Ensure consistent error handling for unauthorized access

The test testForwardCallToReceiveNonPayableWithMsgContextFailsIfSenderIsNotTSS checks that gateway.execute reverts when called by an unauthorized sender with MessageContext. This is correctly implemented. Ensure that the revert message AccessControlUnauthorizedAccount matches the contract's access control mechanisms.

You can verify the access control enforcement with:

v2/test/GatewayZEVM.t.sol (2)

310-312: Verify the use of gasLimit: 0 in CallOptions.

In the emit Withdrawn statement of testWithdrawZETA, the CallOptions is set with gasLimit: 0. Ensure that setting gasLimit to zero is intentional and does not lead to unexpected behavior during execution.


369-378: Confirm gasLimit: 0 in CallOptions for testWithdrawZETAWithMessage.

Again, CallOptions is configured with gasLimit: 0. Please verify that a zero gas limit is appropriate for this test and won't affect the functionality negatively.

@@ -111,6 +114,21 @@ interface IGatewayEVM is IGatewayEVMErrors, IGatewayEVMEvents {
/// @return The result of the contract call.
function execute(address destination, bytes calldata data) external payable returns (bytes memory);

/// @notice Executes a call to a destination address without ERC20 tokens.
/// @dev This function can only be called by the TSS address and it is payable.
/// @param messageContext Message context containing sender and arbitrary call flag.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Inconsistent documentation for messageContext parameter

The documentation for the messageContext parameter states: "Message context containing sender and arbitrary call flag." However, the MessageContext struct only contains the sender field without an arbitrary call flag.

To resolve this inconsistency, please update the documentation or include the arbitraryCall flag in the MessageContext struct.

Option 1: Update the documentation

-   /// @param messageContext Message context containing sender and arbitrary call flag.
+   /// @param messageContext Message context containing sender information.

Option 2: Add arbitraryCall flag to MessageContext struct

 struct MessageContext {
     address sender;
+    bool arbitraryCall;
 }

Please choose the appropriate option based on the intended functionality.

Committable suggestion was skipped due to low confidence.

Comment on lines +22 to 24
CallOptions callOptions,
RevertOptions revertOptions
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Changing event parameters affects event signatures

Replacing the uint256 gasLimit parameter with CallOptions callOptions in the Called and Withdrawn events changes their event signatures. This may impact external contracts or systems that rely on these events.

Consider the implications of altering event signatures:

  • Compatibility: External listeners or dApps that decode these events may fail or produce incorrect results due to the changed parameters.
  • Migration Plan: If backward compatibility is required, consider emitting new events with different names or maintaining the old events alongside the new ones.

Also applies to: 46-48

@@ -163,7 +178,7 @@ contract GatewayEVM is
if (!resetApproval(token, to)) revert ApprovalFailed();
if (!IERC20(token).approve(to, amount)) revert ApprovalFailed();
// Execute the call on the target contract
_execute(to, data);
_executeArbitraryCall(to, data);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle return values in executeWithERC20

In the executeWithERC20 function, the result of the _executeArbitraryCall is not captured or handled.

Consider capturing the result for logging or further processing:

// Existing code
_executeArbitraryCall(to, data);

// Suggested change
bytes memory result = _executeArbitraryCall(to, data);

This allows you to use the result if needed.

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
_executeArbitraryCall(to, data);
bytes memory result = _executeArbitraryCall(to, data);

Comment on lines +429 to +430
return Callable(destination).onCall{ value: msg.value }(messageContext, data);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle potential failures in _executeAuthenticatedCall

The function _executeAuthenticatedCall calls onCall on the destination contract but does not handle the scenario where the call fails.

Consider adding a check to ensure the call was successful:

-function _executeAuthenticatedCall(
-    MessageContext calldata messageContext,
-    address destination,
-    bytes calldata data
-) private returns (bytes memory) {
-    return Callable(destination).onCall{ value: msg.value }(messageContext, data);
-}
+function _executeAuthenticatedCall(
+    MessageContext calldata messageContext,
+    address destination,
+    bytes calldata data
+) private returns (bytes memory) {
+    bytes memory result = Callable(destination).onCall{ value: msg.value }(messageContext, data);
+    // Handle failure if necessary
+    return result;
+}

Alternatively, you can use a low-level call to capture the success status:

function _executeAuthenticatedCall(
    MessageContext calldata messageContext,
    address destination,
    bytes calldata data
) private returns (bytes memory) {
    (bool success, bytes memory result) = address(destination).call{ value: msg.value }(
        abi.encodeWithSelector(Callable.onCall.selector, messageContext, data)
    );
    if (!success) revert ExecutionFailed();
    return result;
}

This ensures that any failure during the call is appropriately handled.

Committable suggestion was skipped due to low confidence.

Comment on lines +149 to 153
if (destination == address(0)) revert ZeroAddress();
bytes memory result = _executeArbitraryCall(destination, data);

emit Executed(destination, msg.value, data);

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Missing nonReentrant modifier in overloaded execute function

The overloaded execute function for arbitrary calls does not have the nonReentrant modifier, which could expose the contract to reentrancy attacks.

Add the nonReentrant modifier to the function:

function execute(
    address destination,
    bytes calldata data
)
    external
    payable
    onlyRole(TSS_ROLE)
    whenNotPaused
+   nonReentrant
    returns (bytes memory)
{
    // Function body
}

This adds an extra layer of security against reentrancy.

Committable suggestion was skipped due to low confidence.

/// @param amount The amount of tokens to withdraw.
/// @param zrc20 The address of the ZRC20 token.
/// @param message The calldata to pass to the contract call.
/// @param callOptions Call options including gas limit and arbirtrary call flag.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct misspelling in documentation comments

The word "arbirtrary" is misspelled in the documentation comments. It should be "arbitrary".

Apply the following diffs to fix the typo:

At line 201:

-    /// @param callOptions Call options including gas limit and arbirtrary call flag.
+    /// @param callOptions Call options including gas limit and arbitrary call flag.

At line 305:

-    /// @param callOptions Call options including gas limit and arbirtrary call flag.
+    /// @param callOptions Call options including gas limit and arbitrary call flag.

At line 332:

-    /// @param callOptions Call options including gas limit and arbirtrary call flag.
+    /// @param callOptions Call options including gas limit and arbitrary call flag.

Also applies to: 305-305, 332-332

Comment on lines +196 to +228
/// @notice Withdraw ZRC20 tokens and call a smart contract on an external chain.
/// @param receiver The receiver address on the external chain.
/// @param amount The amount of tokens to withdraw.
/// @param zrc20 The address of the ZRC20 token.
/// @param message The calldata to pass to the contract call.
/// @param callOptions Call options including gas limit and arbirtrary call flag.
/// @param revertOptions Revert options.
function withdrawAndCall(
bytes memory receiver,
uint256 amount,
address zrc20,
bytes calldata message,
CallOptions calldata callOptions,
RevertOptions calldata revertOptions
)
external
nonReentrant
whenNotPaused
{
if (receiver.length == 0) revert ZeroAddress();
if (amount == 0) revert InsufficientZRC20Amount();

uint256 gasFee = _withdrawZRC20WithGasLimit(amount, zrc20, callOptions.gasLimit);
emit Withdrawn(
msg.sender,
0,
receiver,
zrc20,
amount,
gasFee,
IZRC20(zrc20).PROTOCOL_FLAT_FEE(),
message,
callOptions,
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring to reduce code duplication

Multiple functions such as withdrawAndCall and call have overloaded versions with similar code structures. Consider refactoring these functions to reduce code duplication, improve maintainability, and adhere to the DRY (Don't Repeat Yourself) principle.

One possible approach is to have the functions that accept a gasLimit parameter internally create a CallOptions object and then call the function that accepts CallOptions, thereby centralizing the logic.

Also applies to: 308-326, 334-345, 364-366


⚠️ Potential issue

Add unit tests for the new functions to improve code coverage

The newly added functions withdrawAndCall and call are significant and should be thoroughly tested. Please add unit tests covering various scenarios, including edge cases, to ensure their correctness and reliability.

Also applies to: 308-326, 334-345

Comment on lines +368 to +385
function _call(
bytes memory receiver,
address zrc20,
bytes calldata message,
CallOptions memory callOptions,
RevertOptions memory revertOptions
)
internal
{
if (receiver.length == 0) revert ZeroAddress();
if (message.length == 0) revert EmptyMessage();

(address gasZRC20, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(gasLimit);
(address gasZRC20, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(callOptions.gasLimit);
if (!IZRC20(gasZRC20).transferFrom(msg.sender, PROTOCOL_ADDRESS, gasFee)) {
revert GasFeeTransferFailed();
}

emit Called(msg.sender, zrc20, receiver, message, gasLimit, revertOptions);
emit Called(msg.sender, zrc20, receiver, message, callOptions, revertOptions);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add validation for 'zrc20' address in '_call' function

The _call function does not validate the zrc20 address. If zrc20 is the zero address, it could lead to unintended behavior or errors. Add a check to ensure that zrc20 is not the zero address.

Apply the following diff to add the validation:

 function _call(
     bytes memory receiver,
     address zrc20,
     bytes calldata message,
     CallOptions memory callOptions,
     RevertOptions memory revertOptions
 )
     internal
 {
+    if (zrc20 == address(0)) revert ZeroAddress();
     if (receiver.length == 0) revert ZeroAddress();
     if (message.length == 0) revert EmptyMessage();
     // rest of the code
 }
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
function _call(
bytes memory receiver,
address zrc20,
bytes calldata message,
CallOptions memory callOptions,
RevertOptions memory revertOptions
)
internal
{
if (receiver.length == 0) revert ZeroAddress();
if (message.length == 0) revert EmptyMessage();
(address gasZRC20, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(gasLimit);
(address gasZRC20, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(callOptions.gasLimit);
if (!IZRC20(gasZRC20).transferFrom(msg.sender, PROTOCOL_ADDRESS, gasFee)) {
revert GasFeeTransferFailed();
}
emit Called(msg.sender, zrc20, receiver, message, gasLimit, revertOptions);
emit Called(msg.sender, zrc20, receiver, message, callOptions, revertOptions);
function _call(
bytes memory receiver,
address zrc20,
bytes calldata message,
CallOptions memory callOptions,
RevertOptions memory revertOptions
)
internal
{
if (zrc20 == address(0)) revert ZeroAddress();
if (receiver.length == 0) revert ZeroAddress();
if (message.length == 0) revert EmptyMessage();
(address gasZRC20, uint256 gasFee) = IZRC20(zrc20).withdrawGasFeeWithGasLimit(callOptions.gasLimit);
if (!IZRC20(gasZRC20).transferFrom(msg.sender, PROTOCOL_ADDRESS, gasFee)) {
revert GasFeeTransferFailed();
}
emit Called(msg.sender, zrc20, receiver, message, callOptions, revertOptions);

Comment on lines +207 to +213
function testForwardCallToReceiveOnCallFails() public {
bytes memory data = abi.encodeWithSignature("onCall((address),bytes)", address(123), bytes(""));

vm.prank(tssAddress);
vm.expectRevert(NotAllowedToCallOnCall.selector);
gateway.execute(address(receiver), data);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the abi.encodeWithSignature usage for tuple parameters

In line 208, you're encoding a function call with a tuple parameter using abi.encodeWithSignature. The syntax for encoding tuples requires careful formatting. The current code may not encode the parameters as intended.

Consider updating the code to properly encode the tuple parameter:

-bytes memory data = abi.encodeWithSignature("onCall((address),bytes)", address(123), bytes(""));
+bytes memory data = abi.encodeWithSignature("onCall((address,bytes))", (address(123), bytes("")));

This change ensures that the tuple (address, bytes) is correctly encoded as a single parameter.

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
function testForwardCallToReceiveOnCallFails() public {
bytes memory data = abi.encodeWithSignature("onCall((address),bytes)", address(123), bytes(""));
vm.prank(tssAddress);
vm.expectRevert(NotAllowedToCallOnCall.selector);
gateway.execute(address(receiver), data);
}
function testForwardCallToReceiveOnCallFails() public {
bytes memory data = abi.encodeWithSignature("onCall((address,bytes))", (address(123), bytes("")));
vm.prank(tssAddress);
vm.expectRevert(NotAllowedToCallOnCall.selector);
gateway.execute(address(receiver), data);
}

Comment on lines +485 to 487
emit Called(owner, address(zrc20), abi.encodePacked(addr1), message, callOptions, revertOptions);
gateway.call(abi.encodePacked(addr1), address(zrc20), message, 1, revertOptions);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Inconsistent usage of callOptions in testCall function.

In the testCall function, the emit Called event uses callOptions, but the subsequent gateway.call invocation passes 1 instead of callOptions.

emit Called(owner, address(zrc20), abi.encodePacked(addr1), message, callOptions, revertOptions);
gateway.call(abi.encodePacked(addr1), address(zrc20), message, 1, revertOptions);

This inconsistency may lead to unintended behavior in the test. Ensure both the event emission and the function call use callOptions for consistency.

Apply this diff to fix the inconsistency:

-            gateway.call(abi.encodePacked(addr1), address(zrc20), message, 1, revertOptions);
+            gateway.call(abi.encodePacked(addr1), address(zrc20), message, callOptions, revertOptions);

@skosito
Copy link
Contributor Author

skosito commented Sep 26, 2024

@lumtis @fadeev could you please check this one?

@skosito skosito merged commit 7175604 into main Sep 27, 2024
14 checks passed
@skosito skosito deleted the protocol-integration-auth-call branch September 27, 2024 11:36
@@ -163,7 +178,7 @@ contract GatewayEVM is
if (!resetApproval(token, to)) revert ApprovalFailed();
if (!IERC20(token).approve(to, amount)) revert ApprovalFailed();
// Execute the call on the target contract
_execute(to, data);
_executeArbitraryCall(to, data);
Copy link

Choose a reason for hiding this comment

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

Why do we only allow for arbitrary and not for authenticated calls when executing with ERC20?

Copy link

Choose a reason for hiding this comment

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

Same as #355 (comment)

0,
0,
message,
CallOptions({ gasLimit: 0, isArbitraryCall: true }),
Copy link

Choose a reason for hiding this comment

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

Won't the call always fail on the other side as we hardcode a gasLimit of 0? (Same for other occurrences)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i think it is 0 because it is not provided in arguments and it wont fail since it can be handled on protocol side

Copy link

Choose a reason for hiding this comment

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

But who pays for the gas in that case?

/// @param amount The amount of tokens to withdraw.
/// @param chainId Chain id of the external chain.
/// @param message The calldata to pass to the contract call.
/// @param callOptions Call options including gas limit and arbirtrary call flag.
Copy link

Choose a reason for hiding this comment

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

Typo in "arbitrary"

uint256 amount,
address zrc20,
bytes calldata message,
CallOptions calldata callOptions,
Copy link

Choose a reason for hiding this comment

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

This would, by my understanding allow for an authenticated call with an erc20 transfer on the other side. However, this is not possible as executeWithERC20() only implements the arbitrary call

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i think we can have authenticated calls for executeWithERC20, but i think initially at least we just wanted it for execute, @lumtis was this intentional or we need authenticated calls for erc20 as well?

Copy link

Choose a reason for hiding this comment

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

When you look at executeWithERC20 you can see that it only allows for arbitrary calls.

function executeWithERC20(
    address token,
    address to,
    uint256 amount,
    bytes calldata data
)
    public
    onlyRole(ASSET_HANDLER_ROLE)
    whenNotPaused
    nonReentrant
{
    if (amount == 0) revert InsufficientERC20Amount();
    if (to == address(0)) revert ZeroAddress();
    // Approve the target contract to spend the tokens
    if (!resetApproval(token, to)) revert ApprovalFailed();
    if (!IERC20(token).approve(to, amount)) revert ApprovalFailed();
    // Execute the call on the target contract
    _executeArbitraryCall(to, data);

    // Reset approval
    if (!resetApproval(token, to)) revert ApprovalFailed();

    // Transfer any remaining tokens back to the custody/connector contract
    uint256 remainingBalance = IERC20(token).balanceOf(address(this));
    if (remainingBalance > 0) {
        transferToAssetHandler(token, remainingBalance);
    }

    emit ExecutedWithERC20(token, to, amount, data);
}

But in the GatewayZEVM.sol someone could set the authenticated call to true in the call options.

Copy link
Contributor Author

@skosito skosito Oct 10, 2024

Choose a reason for hiding this comment

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

yes, i now remember this was also a question from me in PR description in original PR (2nd question in questions part) that was closed, but we didnt discuss it: #350, i am also leaning towards that its needed

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.

Enable calling contracts on connected chains with caller info
6 participants