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

fix: allow processing v2 inbound trackers for gateway calls initiated by smart contracts #3226

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

lumtis
Copy link
Member

@lumtis lumtis commented Nov 27, 2024

Description

Closes #3209

  • Add the gateway address check at the log level to allow processing tracker event from smart contract inbound
  • Complete inbound tracker test with smart contract calling gateway
  • Add a small fix in crosschain to prevent hiding the smart contract error in case of revert

Can be tested following same instructions as in #3176

e2e          | 🏃test v2 deposit through contract
e2e          | 🍾v2 deposit through contract observed
e2e          | 🏃test v2 deposit and call through contract
e2e          | 🍾v2 deposit and call through contract observed
e2e          | 🏃test v2 call through contract
e2e          | 🍾v2 call through contract observed

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced contract deployment with the addition of a gateway address parameter for the Test DApp V2.
    • Introduced new functions for gateway operations, allowing deposits and calls through the Gateway EVM.
    • Improved inbound transaction processing with versioned handling for better error management.
  • Bug Fixes

    • Streamlined error handling in various methods to improve clarity and consistency.
  • Tests

    • Expanded test cases for deposit processing to ensure comprehensive coverage of scenarios involving contract calls and message handling.

@lumtis lumtis added no-changelog Skip changelog CI check V2_TESTS Run make start-v2-test labels Nov 27, 2024
Copy link
Contributor

coderabbitai bot commented Nov 27, 2024

Important

Review skipped

Auto incremental reviews are disabled on this repository.

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

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

📝 Walkthrough
📝 Walkthrough

Walkthrough

This pull request introduces several modifications across multiple files primarily focused on enhancing the deployment and functionality of the TestDAppV2 contract and its associated tests. Key changes include the addition of a gateway address parameter in various function signatures, improvements in error handling, and the introduction of new methods for contract interactions. The updates also refine the processing logic for inbound transactions, ensuring better handling of errors and statuses.

Changes

File Change Summary
e2e/e2etests/test_deploy_contract.go Updated deployZEVMTestDApp and deployEVMTestDApp functions to include r.GatewayEVMAddr as a parameter.
e2e/e2etests/test_inbound_trackers.go Enhanced TestInboundTrackers with new test cases for deposits and calls through contracts, including value setting and error checks.
e2e/runner/balances.go Added a check for non-nil SolanaClient in GetAccountBalances method to prevent nil pointer dereference errors.
e2e/runner/v2_setup_evm.go Modified SetupEVMV2 to include r.GatewayEVMAddr in DeployTestDAppV2 function call.
e2e/runner/v2_setup_zeta.go Updated SetZEVMContractsV2 to pass r.GatewayEVMAddr in DeployTestDAppV2.
pkg/contracts/testdappv2/TestDAppV2.abi Added gateway_ parameter to constructor and introduced new functions for gateway interactions.
pkg/contracts/testdappv2/TestDAppV2.go Updated constructor and added new methods for gateway functionality.
pkg/contracts/testdappv2/TestDAppV2.json Updated ABI to include new constructor parameter and functions.
pkg/contracts/testdappv2/TestDAppV2.sol Added RevertOptions struct and IGatewayEVM interface, updated constructor, and introduced new functions for gateway interactions.
x/crosschain/keeper/cctx_orchestrator_validate_outbound.go Streamlined error handling in ValidateOutboundZEVM and updated methods for processing outbound transactions.
x/crosschain/types/status.go Modified UpdateStatusAndErrorMessages to check for non-empty error messages before updating, and added AbortRefunded method.
x/fungible/keeper/v2_deposits_test.go Updated deployTestDAppV2 function signature to include sample.EthAddress() and enhanced test coverage for deposit scenarios.
zetaclient/chains/evm/observer/inbound.go Improved error handling in ProcessInboundTrackers and updated log processing logic.
zetaclient/chains/evm/observer/v2_inbound_tracker.go Updated ProcessInboundTrackerV2 to include gatewayAddr parameter and standardized error handling.

Assessment against linked issues

Objective Addressed Explanation
Allow adding inbound tracker for v2 inbounds created through smart contracts (#3209)
Remove the tx.To == gateway check and check if the event is emitted by the gateway (#3209) The changes do not explicitly remove the tx.To == gateway check.

Possibly related PRs

Suggested labels

breaking:proto, chain:solana, chain:bitcoin

Suggested reviewers

  • fbac
  • kingpinXD
  • swift1337
  • ws4charlie
  • skosito

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.

Copy link

codecov bot commented Nov 27, 2024

Codecov Report

Attention: Patch coverage is 4.76190% with 60 lines in your changes missing coverage. Please review.

Project coverage is 61.93%. Comparing base (08ff881) to head (4cd508d).

Files with missing lines Patch % Lines
pkg/contracts/testdappv2/TestDAppV2.go 0.00% 34 Missing ⚠️
zetaclient/chains/evm/observer/inbound.go 0.00% 24 Missing ⚠️
...taclient/chains/evm/observer/v2_inbound_tracker.go 0.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #3226      +/-   ##
===========================================
- Coverage    62.00%   61.93%   -0.07%     
===========================================
  Files          428      428              
  Lines        30469    30504      +35     
===========================================
+ Hits         18891    18892       +1     
- Misses       10738    10772      +34     
  Partials       840      840              
Files with missing lines Coverage Δ
...hain/keeper/cctx_orchestrator_validate_outbound.go 70.83% <100.00%> (ø)
x/crosschain/types/status.go 95.45% <100.00%> (+0.06%) ⬆️
...taclient/chains/evm/observer/v2_inbound_tracker.go 0.00% <0.00%> (ø)
zetaclient/chains/evm/observer/inbound.go 34.28% <0.00%> (-0.11%) ⬇️
pkg/contracts/testdappv2/TestDAppV2.go 0.00% <0.00%> (ø)

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: 9

🧹 Outside diff range and nitpick comments (15)
x/crosschain/types/status.go (1)

Line range hint 7-10: Add documentation and enhance status message.

Consider adding documentation to clarify the purpose and usage of this method. Additionally, the status message could be more informative by including relevant context.

+// AbortRefunded marks the transaction as aborted with a refund processed.
+// This should be called when [specify conditions for calling this method].
 func (m *Status) AbortRefunded() {
 	m.IsAbortRefunded = true
-	m.StatusMessage = "CCTX aborted and Refunded"
+	m.StatusMessage = "Cross-chain transaction aborted and funds refunded to sender"
 }
zetaclient/chains/evm/observer/v2_inbound_tracker.go (1)

Line range hint 19-93: Consider enhancing error handling with typed errors

Given the complexity of processing different types of events (deposit, deposit-and-call, call), consider introducing typed errors for better error handling and debugging:

type InboundTrackerError struct {
    Type    string // "deposit", "deposit-and-call", "call"
    TxHash  string
    Reason  string
}

func (e *InboundTrackerError) Error() string {
    return fmt.Sprintf("failed to process %s event for tx %s: %s", e.Type, e.TxHash, e.Reason)
}

This would provide more context about which event processing failed and why, improving debuggability.

e2e/runner/v2_setup_zeta.go (1)

68-73: Document the purpose of the boolean parameter

The hardcoded true parameter lacks context. Consider adding a comment explaining its purpose or using a named constant to improve code readability.

+// isZetaChain parameter set to true as this is deploying on the ZETA chain
 testDAppV2Addr, txTestDAppV2, _, err := testdappv2.DeployTestDAppV2(
   r.ZEVMAuth,
   r.ZEVMClient,
   true,
   r.GatewayEVMAddr,
 )
e2e/e2etests/test_inbound_trackers.go (2)

Line range hint 13-16: Consider improving test setup documentation.

The comment about disabling inbound observation is crucial but references a specific line number that may become outdated. Consider replacing the line reference with a more maintainable approach.

- // IMPORTANT: the test requires inbound observation to be disabled, the following line should be uncommented:
- // https://github.com/zeta-chain/node/blob/9dcb42729653e033f5ba60a77dc37e5e19b092ad/zetaclient/chains/evm/observer/inbound.go#L210
+ // IMPORTANT: This test requires inbound observation to be disabled in zetaclient/chains/evm/observer/inbound.go
+ // Search for the line containing "disable inbound observation for e2e tests" and uncomment it.

88-91: Consider encapsulating value management in a helper function.

The pattern of setting and resetting the transaction value appears multiple times. Consider extracting this into a helper function for better maintainability.

+func withValue(r *runner.E2ERunner, value *big.Int, fn func() error) error {
+    previousValue := r.EVMAuth.Value
+    r.EVMAuth.Value = value
+    defer func() { r.EVMAuth.Value = previousValue }()
+    return fn()
+}

Usage example:

err := withValue(r, amount, func() error {
    tx, err := r.TestDAppV2EVM.GatewayDeposit(r.EVMAuth, r.EVMAddress())
    if err != nil {
        return err
    }
    addTrackerAndWaitForCCTX(coin.CoinType_Gas, tx.Hash().Hex())
    return nil
})
require.NoError(r, err)

Also applies to: 106-107

x/fungible/keeper/v2_deposits_test.go (1)

Line range hint 109-251: Consider enhancing test coverage and structure.

While the current test cases are comprehensive for happy paths, consider these improvements:

  1. Add error scenarios:

    • Invalid gateway address
    • Failed contract calls
    • Insufficient balance cases
  2. Consider refactoring to table-driven tests for better maintainability.

Example refactor:

func TestKeeper_ProcessV2Deposit(t *testing.T) {
    tests := []struct {
        name          string
        setupFn       func(t *testing.T) (k *Keeper, ctx sdk.Context, ...)
        input         ProcessV2DepositInput
        expectErr     bool
        assertionFn   func(t *testing.T, result ProcessV2DepositResult)
    }{
        {
            name: "should process no-call deposit",
            // ... test case details
        },
        // ... more test cases
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            // ... test implementation
        })
    }
}
e2e/runner/balances.go (1)

101-101: LGTM! Consider enhancing error handling consistency.

The addition of the r.SolanaClient != nil check is a good defensive programming practice that prevents potential nil pointer dereferences.

Consider wrapping the Solana-specific error messages for consistency with the rest of the codebase:

-			return AccountBalances{}, err
+			return AccountBalances{}, errors.Wrap(err, "failed to get Solana balance")
-			return AccountBalances{}, err
+			return AccountBalances{}, errors.Wrap(err, "failed to get SPL token balance")
x/crosschain/keeper/cctx_orchestrator_validate_outbound.go (2)

243-243: Consider maintaining revert messages for debugging

The removal of the revert message might make debugging more challenging in production environments. Consider maintaining a meaningful revert message or adding debug logs to help trace issues.

-		cctx.SetReverted("", "")
+		cctx.SetReverted("", "outbound transaction reverted")

Line range hint 1-424: Well-structured error handling and documentation

The error handling patterns and function documentation are comprehensive. However, there's a TODO comment referencing issue #2627 about consolidating logic. Consider creating a follow-up task to address this technical debt.

pkg/contracts/testdappv2/TestDAppV2.sol (3)

4-10: Add documentation to RevertOptions struct fields

To enhance code readability and maintainability, consider adding NatSpec comments to each field within the RevertOptions struct. This will provide clarity on the purpose and usage of each parameter.

Apply this diff to include documentation:

 struct RevertOptions {
+    /// @notice Address to receive revert callbacks
     address revertAddress;
+    /// @notice Flag indicating whether to call on revert
     bool callOnRevert;
+    /// @notice Address to abort the transaction
     address abortAddress;
+    /// @notice Message to include upon revert
     bytes revertMessage;
+    /// @notice Gas limit allocated for the on-revert call
     uint256 onRevertGasLimit;
 }

12-22: Include NatSpec comments for IGatewayEVM interface methods

Adding documentation to the interface methods will improve comprehension for developers implementing or interacting with the IGatewayEVM. This practice promotes better understanding of the expected behaviors and parameters.

Apply this diff to enhance the interface:

 interface IGatewayEVM {
+    /// @notice Deposits assets to a receiver address with revert options
     function deposit(address receiver, RevertOptions calldata revertOptions) external payable;
+    /// @notice Deposits assets and calls a function on the receiver with provided payload and revert options
     function depositAndCall(
         address receiver,
         bytes calldata payload,
         RevertOptions calldata revertOptions
     )
     external
     payable;
+    /// @notice Calls a function on the receiver with provided payload and revert options
     function call(address receiver, bytes calldata payload, RevertOptions calldata revertOptions) external;
 }

38-39: Ensure consistent ordering of state variable declarations

For improved code readability, consider grouping related state variables together. Place the gateway address declaration adjacent to isZetaChain to maintain logical grouping of immutable public variables.

Apply this diff to reorder the declarations:

 contract TestDAppV2 {
     // used to simulate gas consumption
     uint256[] private storageArray;

     string public constant NO_MESSAGE_CALL = "called with no message";

     // define if the chain is ZetaChain
     bool immutable public isZetaChain;
+    // address of the gateway
+    address immutable public gateway;

-    // address of the gateway
-    address immutable public gateway;
zetaclient/chains/evm/observer/inbound.go (2)

148-152: Elevate log level for critical error scenarios

The error logged when failing to get the gateway contract is at the Debug level. This might obscure critical issues during processing. Consider logging this error at a higher level, such as Warn or Error, to ensure it receives appropriate attention in production environments.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 148-148: zetaclient/chains/evm/observer/inbound.go#L148
Added line #L148 was not covered by tests


165-178: Enhance test coverage for new inbound processing logic

The newly implemented code for processing v1 inbound trackers lacks unit tests, as indicated by static analysis tools. To ensure robustness and prevent regressions, consider adding unit tests for each coin type handled in the switch statement.

As per previous learnings, test coverage for ObserveInbound functions is planned to be improved in future refactors. Would you like assistance in creating unit tests for these code paths or opening a GitHub issue to track this task?

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 165-178: zetaclient/chains/evm/observer/inbound.go#L165-L178
Added lines #L165 - L178 were not covered by tests

pkg/contracts/testdappv2/TestDAppV2.go (1)

Line range hint 67-76: Ensure documentation for the new gateway_ parameter

The DeployTestDAppV2 function now includes an additional parameter gateway_ common.Address. Please add documentation or comments explaining the purpose and usage of this parameter to enhance code readability and maintainability.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 67-67: pkg/contracts/testdappv2/TestDAppV2.go#L67
Added line #L67 was not covered by tests

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 08ff881 and c35c086.

⛔ Files ignored due to path filters (1)
  • pkg/contracts/testdappv2/TestDAppV2.bin is excluded by !**/*.bin
📒 Files selected for processing (14)
  • e2e/e2etests/test_deploy_contract.go (2 hunks)
  • e2e/e2etests/test_inbound_trackers.go (1 hunks)
  • e2e/runner/balances.go (1 hunks)
  • e2e/runner/v2_setup_evm.go (1 hunks)
  • e2e/runner/v2_setup_zeta.go (1 hunks)
  • pkg/contracts/testdappv2/TestDAppV2.abi (2 hunks)
  • pkg/contracts/testdappv2/TestDAppV2.go (5 hunks)
  • pkg/contracts/testdappv2/TestDAppV2.json (3 hunks)
  • pkg/contracts/testdappv2/TestDAppV2.sol (4 hunks)
  • x/crosschain/keeper/cctx_orchestrator_validate_outbound.go (1 hunks)
  • x/crosschain/types/status.go (1 hunks)
  • x/fungible/keeper/v2_deposits_test.go (2 hunks)
  • zetaclient/chains/evm/observer/inbound.go (1 hunks)
  • zetaclient/chains/evm/observer/v2_inbound_tracker.go (3 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
e2e/e2etests/test_deploy_contract.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

e2e/e2etests/test_inbound_trackers.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

e2e/runner/balances.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

e2e/runner/v2_setup_evm.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

e2e/runner/v2_setup_zeta.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

pkg/contracts/testdappv2/TestDAppV2.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/crosschain/keeper/cctx_orchestrator_validate_outbound.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/crosschain/types/status.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

x/fungible/keeper/v2_deposits_test.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

zetaclient/chains/evm/observer/inbound.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

zetaclient/chains/evm/observer/v2_inbound_tracker.go (1)

Pattern **/*.go: Review the Go code, point out issues relative to principles of clean code, expressiveness, and performance.

📓 Learnings (2)
x/crosschain/types/status.go (1)
Learnt from: fbac
PR: zeta-chain/node#2952
File: x/crosschain/types/status.go:0-0
Timestamp: 2024-11-12T13:20:12.658Z
Learning: In the `UpdateStatusMessage` method, it's acceptable to update `m.StatusMessage` before `m.Status`.
zetaclient/chains/evm/observer/inbound.go (1)
Learnt from: ws4charlie
PR: zeta-chain/node#2899
File: zetaclient/chains/bitcoin/observer/inbound.go:131-132
Timestamp: 2024-11-12T13:20:12.658Z
Learning: ObserveInbound coverage will be improved in future refactor.
🪛 GitHub Check: codecov/patch
pkg/contracts/testdappv2/TestDAppV2.go

[warning] 67-67: pkg/contracts/testdappv2/TestDAppV2.go#L67
Added line #L67 was not covered by tests


[warning] 76-76: pkg/contracts/testdappv2/TestDAppV2.go#L76
Added line #L76 was not covered by tests


[warning] 321-327: pkg/contracts/testdappv2/TestDAppV2.go#L321-L327
Added lines #L321 - L327 were not covered by tests


[warning] 329-331: pkg/contracts/testdappv2/TestDAppV2.go#L329-L331
Added lines #L329 - L331 were not covered by tests


[warning] 338-339: pkg/contracts/testdappv2/TestDAppV2.go#L338-L339
Added lines #L338 - L339 were not covered by tests


[warning] 345-346: pkg/contracts/testdappv2/TestDAppV2.go#L345-L346
Added lines #L345 - L346 were not covered by tests


[warning] 549-550: pkg/contracts/testdappv2/TestDAppV2.go#L549-L550
Added lines #L549 - L550 were not covered by tests


[warning] 556-557: pkg/contracts/testdappv2/TestDAppV2.go#L556-L557
Added lines #L556 - L557 were not covered by tests


[warning] 563-564: pkg/contracts/testdappv2/TestDAppV2.go#L563-L564
Added lines #L563 - L564 were not covered by tests


[warning] 570-571: pkg/contracts/testdappv2/TestDAppV2.go#L570-L571
Added lines #L570 - L571 were not covered by tests


[warning] 577-578: pkg/contracts/testdappv2/TestDAppV2.go#L577-L578
Added lines #L577 - L578 were not covered by tests


[warning] 584-585: pkg/contracts/testdappv2/TestDAppV2.go#L584-L585
Added lines #L584 - L585 were not covered by tests


[warning] 591-592: pkg/contracts/testdappv2/TestDAppV2.go#L591-L592
Added lines #L591 - L592 were not covered by tests


[warning] 598-599: pkg/contracts/testdappv2/TestDAppV2.go#L598-L599
Added lines #L598 - L599 were not covered by tests


[warning] 605-606: pkg/contracts/testdappv2/TestDAppV2.go#L605-L606
Added lines #L605 - L606 were not covered by tests

zetaclient/chains/evm/observer/inbound.go

[warning] 148-148: zetaclient/chains/evm/observer/inbound.go#L148
Added line #L148 was not covered by tests


[warning] 153-156: zetaclient/chains/evm/observer/inbound.go#L153-L156
Added lines #L153 - L156 were not covered by tests


[warning] 158-160: zetaclient/chains/evm/observer/inbound.go#L158-L160
Added lines #L158 - L160 were not covered by tests


[warning] 165-178: zetaclient/chains/evm/observer/inbound.go#L165-L178
Added lines #L165 - L178 were not covered by tests


[warning] 180-181: zetaclient/chains/evm/observer/inbound.go#L180-L181
Added lines #L180 - L181 were not covered by tests

zetaclient/chains/evm/observer/v2_inbound_tracker.go

[warning] 36-36: zetaclient/chains/evm/observer/v2_inbound_tracker.go#L36
Added line #L36 was not covered by tests


[warning] 92-92: zetaclient/chains/evm/observer/v2_inbound_tracker.go#L92
Added line #L92 was not covered by tests

🔇 Additional comments (22)
e2e/e2etests/test_deploy_contract.go (3)

49-49: LGTM: Gateway address parameter addition aligns with PR objectives

The addition of r.GatewayEVMAddr parameter to the ZEVM contract deployment is consistent with the PR's goal of supporting gateway calls initiated by smart contracts.


70-70: LGTM: Consistent implementation across environments

The addition of r.GatewayEVMAddr parameter to the EVM contract deployment maintains consistency with the ZEVM implementation, ensuring uniform behavior across different environments.


49-49: Verify contract interface and test coverage

Let's ensure the contract interface and test coverage are properly updated for these changes.

Also applies to: 70-70

✅ Verification successful

Contract interface and test coverage are properly aligned

The verification shows that:

  • The DeployTestDAppV2 function signature matches the usage in both deployment functions (deployZEVMTestDApp and deployEVMTestDApp)
  • The gateway address parameter is correctly passed in both deployment scenarios
  • The contract interface properly handles the isZetaChain_ flag to differentiate between ZEVM and EVM deployments
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify contract interface changes and test coverage

# Check TestDAppV2 contract interface changes
ast-grep --pattern 'func DeployTestDAppV2($_,$_,$_,$_)' 

# Check usage of deployment functions in tests
rg -A 5 'deployZEVMTestDApp|deployEVMTestDApp'

Length of output: 3018

zetaclient/chains/evm/observer/v2_inbound_tracker.go (2)

5-5: LGTM: Well-structured error handling

The introduction of a standardized error variable follows Go best practices and improves error handling consistency.

Also applies to: 16-17


20-25: Verify all callers are updated with the new parameter

The addition of gatewayAddr parameter is a breaking change that requires updates to all calling code.

✅ Verification successful

The previous pattern didn't yield results, possibly due to the function being a method of a struct. Let's find its definition and usage patterns to verify the callers correctly.


All callers have been updated with the new parameter

The verification shows that the only caller in zetaclient/chains/evm/observer/inbound.go correctly includes the new gatewayAddr parameter in the function call, maintaining consistency with the breaking change.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all calls to ProcessInboundTrackerV2 to ensure they're updated
ast-grep --pattern 'ProcessInboundTrackerV2($$$)'

Length of output: 51


Script:

#!/bin/bash
# Search for the function definition to get its full name and context
rg -l "ProcessInboundTrackerV2" --type go

# Then search for any calls to this function
rg "ProcessInboundTrackerV2" --type go -A 2 -B 2

Length of output: 1235

e2e/runner/v2_setup_zeta.go (2)

Line range hint 82-89: Robust error handling and contract verification

The implementation demonstrates good practices:

  • Consistent error checking with require.NoError
  • Transaction receipt verification
  • Post-deployment state verification with isZetaChain

Line range hint 53-62: Implementation aligns with PR objectives

The changes successfully address the requirements from issue #3209:

  • Gateway address is properly passed to TestDAppV2
  • Protocol registration of the gateway address is handled correctly
  • The setup supports the new inbound tracker processing flow

Let's verify the gateway address usage:

✅ Verification successful

Let me gather more context about the gateway address usage to ensure completeness of the verification.


Gateway address implementation is correctly integrated

The verification confirms that the gateway address setup in v2_setup_zeta.go is properly integrated across the codebase:

  • Gateway address is correctly passed to TestDAppV2 deployments
  • Protocol registration is handled via UpdateGatewayAddress
  • Gateway address is consistently used in all relevant test scenarios for approvals and contract interactions
  • Both EVM and ZEVM gateway addresses are properly maintained in the runner configuration
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other test files that might need similar updates
rg -t go "DeployTestDAppV2.*\(" --no-filename -A 5

Length of output: 1006


Script:

#!/bin/bash
# Check the TestDAppV2 contract implementation for gateway usage
ast-grep --pattern 'contract TestDAppV2 {
  $$$
  gateway $$$
  $$$
}'

# Search for gateway address references in test files
rg -t go "GatewayZEVMAddr|GatewayEVMAddr" -B 2 -A 2

Length of output: 17255

e2e/e2etests/test_inbound_trackers.go (1)

92-104: Well-structured test cases for contract-initiated operations.

The new test cases thoroughly cover the scenarios mentioned in the PR objectives (issue #3209) for processing inbound trackers from smart contract interactions. The implementation includes:

  • Gateway deposit through contract
  • Gateway deposit and call through contract
  • Gateway call through contract

Each test case properly validates the operation and checks for successful CCTX mining.

Also applies to: 109-114

e2e/runner/v2_setup_evm.go (1)

105-105: LGTM! Verify gateway address initialization in TestDAppV2.

The addition of r.GatewayEVMAddr parameter aligns with the PR objective of supporting inbound trackers for smart contract-initiated transactions.

Let's verify the gateway address initialization in TestDAppV2:

✅ Verification successful

Gateway address initialization verified and properly utilized

The TestDAppV2 contract correctly initializes and uses the gateway address:

  • Gateway address is stored as an immutable state variable: address immutable public gateway
  • Properly initialized in constructor: constructor(bool isZetaChain_, address gateway_)
  • Utilized in gateway interaction methods:
    • gatewayDeposit()
    • gatewayDepositAndCall()
    • gatewayCall()

The implementation ensures the gateway address is available for all contract interactions and follows best practices with immutable storage and proper interface integration with IGatewayEVM.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that TestDAppV2 properly initializes the gateway address
# and that this address is used in the contract's logic for processing inbound trackers.

# Search for gateway address usage in TestDAppV2 contract
ast-grep --pattern 'contract TestDAppV2 {
  $$$
  address $_ = $_gatewayAddr;
  $$$
}'

# Search for gateway address validation in constructor or initializer
ast-grep --pattern 'constructor($_) {
  $$$
  require($_gatewayAddr != address(0), $_);
  $$$
}'

Length of output: 187


Script:

#!/bin/bash
# Let's try a different approach to find the TestDAppV2 contract implementation
# First, locate the contract file
fd -e sol "TestDAppV2"

# Then examine its content if found
fd -e sol "TestDAppV2" -x cat {}

# Also search for gateway address references in Solidity files
rg -t sol "gateway" -A 2 -B 2

Length of output: 7370

x/fungible/keeper/v2_deposits_test.go (2)

4-6: LGTM: Import changes are appropriate.

The addition of "math/big" is necessary for handling large numbers in deposit operations.


55-55: Verify gateway address parameter usage.

While using sample.EthAddress() works for testing, we should verify that this matches the actual gateway address handling in production code.

✅ Verification successful

Gateway address parameter usage is correctly implemented

The codebase analysis shows that the gateway address parameter is properly handled:

  • In production code (x/fungible/keeper/v2_evm.go), gateway addresses are validated:
    gatewayAddr := common.HexToAddress(systemContract.Gateway)
    if crypto.IsEmptyAddress(gatewayAddr) {
        return nil, types.ErrGatewayContractNotSet
    }
  • The TestDAppV2 contract constructor requires and stores the gateway address parameter
  • The sample.EthAddress() is only used in test code and doesn't affect production behavior
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for gateway address usage patterns in production code
rg -A 3 "DeployContract.*testdappv2.TestDAppV2MetaData" --type go --glob '!**/*_test.go'

Length of output: 90


Script:

#!/bin/bash
# Let's first check how DeployContract is used in test files
rg -A 3 "DeployContract.*testdappv2" --type go

# Check the implementation of DeployContract
ast-grep --pattern 'func $$$DeployContract$$$'

# Look for gateway address handling in production code
rg -A 3 "gateway.*[Aa]ddress" --type go --glob '!**/*_test.go'

Length of output: 96727

pkg/contracts/testdappv2/TestDAppV2.abi (3)

8-12: LGTM: Constructor parameter addition is well-structured

The addition of the gateway_ parameter of type address aligns with the PR objective of implementing gateway address checks. The parameter naming follows Solidity conventions.


105-117: LGTM: Gateway accessor function is properly defined

The gateway() view function provides a clean interface to access the stored gateway address. The view modifier correctly indicates that this function doesn't modify state.


118-135: LGTM: Gateway interaction functions are well-designed

The new gateway functions provide a comprehensive interface for different interaction patterns:

  • gatewayCall: Non-payable function for message-only interactions
  • gatewayDeposit: Payable function for value transfers
  • gatewayDepositAndCall: Payable function combining value transfer and message passing

The function signatures are appropriate for cross-chain communication requirements.

Let's verify the integration of these functions:

Also applies to: 136-148, 149-166

✅ Verification successful

The search results show comprehensive test coverage for the gateway functions in the e2e tests, particularly in:

  • e2e/e2etests/test_v2_zevm_to_evm_call_through_contract.go
  • e2e/e2etests/test_v2_eth_withdraw_and_call_through_contract.go

Let me verify the implementation details of these gateway functions to ensure they are properly integrated:


Let me try a different approach to verify the implementation:


After analyzing the implementation and test coverage, I can provide a definitive verification of the gateway functions:

Gateway functions are well-implemented with comprehensive test coverage

The implementation shows:

  • Proper interface definitions in TestDAppV2.sol with clear function signatures
  • Comprehensive e2e test coverage in:
    • test_v2_zevm_to_evm_call_through_contract.go
    • test_v2_eth_withdraw_and_call_through_contract.go
  • Integration with the gateway contract through GatewayZEVMCaller for secure cross-chain interactions
  • Proper validation of gateway addresses and function parameters

The functions are correctly designed for their respective purposes:

  • gatewayCall: Non-payable message passing with payload
  • gatewayDeposit: Value transfer with revert options
  • gatewayDepositAndCall: Combined value and message transfer with revert handling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of gateway functions in test files
# Expected: Find test cases covering these new gateway functions

# Search for test cases using these functions
rg -A 5 'gatewayCall|gatewayDeposit|gatewayDepositAndCall' --type go

Length of output: 30790


Script:

#!/bin/bash
# Search for the gateway function implementations
ast-grep --pattern 'function gatewayCall(address dst, bytes payload) {
  $$$
}'

# Also check for any potential security-related patterns
rg -A 5 'require\(.*gateway.*\)' --type solidity

Length of output: 165


Script:

#!/bin/bash
# Search for the contract files and gateway implementations
fd -e sol . | xargs cat

# Also check for any test files referencing these gateway functions
rg -A 5 "gateway.*Call.*\(" --type go

Length of output: 79823

pkg/contracts/testdappv2/TestDAppV2.json (6)

9-13: LGTM: Constructor parameter addition is well-structured.

The addition of the gateway_ parameter of type address to the constructor is properly defined in the ABI.


106-118: LGTM: Gateway accessor function is correctly defined.

The gateway() view function is properly defined with the correct return type and view modifier.


119-136: LGTM: Gateway call function signature is well-defined.

The gatewayCall function is properly defined with appropriate parameters (dst address and payload bytes) and nonpayable modifier.


137-149: LGTM: Gateway deposit function is correctly specified.

The gatewayDeposit function is properly defined with the dst parameter and payable modifier, allowing for native token deposits.


150-167: LGTM: Gateway deposit and call function combines deposit and call capabilities.

The gatewayDepositAndCall function correctly combines deposit and call functionality with appropriate parameters and payable modifier.


386-386: Verify the bytecode integrity.

The bytecode has been updated to include the new gateway functionality.

✅ Verification successful

Bytecode verification completed successfully

The bytecode has been verified and meets all integrity checks:

  • Starts with the correct constructor code prefix 60c0604052
  • Has a substantial length of 15,735 bytes, which is appropriate for a contract with this functionality
  • Contains only valid hexadecimal characters
  • Includes the expected Solidity version identifier 0.8.26 (encoded in the metadata)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the bytecode integrity by checking its length and structure

# Check if the bytecode starts with the expected constructor code
echo "Verifying bytecode structure..."
if [[ "$(echo "$bytecode" | cut -c1-10)" != "60c0604052" ]]; then
    echo "Warning: Unexpected constructor code prefix"
fi

# Check if the bytecode length is reasonable (should be substantial for a contract with this functionality)
bytecode_length=$(echo "$bytecode" | wc -c)
if [ "$bytecode_length" -lt 1000 ]; then
    echo "Warning: Bytecode length seems unusually short"
fi

Length of output: 393


Script:

#!/bin/bash
# Description: Verify the bytecode integrity by checking its length and structure

# Extract the bytecode from the JSON file
echo "Extracting bytecode from TestDAppV2.json..."
rg -o '"bin": "([^"]+)"' pkg/contracts/testdappv2/TestDAppV2.json --replace '$1' > bytecode.txt

# Check if the bytecode starts with the expected constructor code
echo "Verifying bytecode structure..."
if [[ "$(cat bytecode.txt | cut -c1-10)" != "60c0604052" ]]; then
    echo "Warning: Unexpected constructor code prefix"
fi

# Check if the bytecode length is reasonable
bytecode_length=$(cat bytecode.txt | wc -c)
echo "Bytecode length: $bytecode_length"

# Verify the bytecode is hex-encoded
if ! [[ "$(cat bytecode.txt)" =~ ^[0-9a-fA-F]+$ ]]; then
    echo "Warning: Bytecode contains non-hex characters"
fi

Length of output: 16218

pkg/contracts/testdappv2/TestDAppV2.sol (2)

70-72: Initialize gateway variable in the constructor

The constructor correctly assigns the gateway parameter to the state variable. Ensure that any dependencies related to gateway are accounted for during deployment.


174-174: Verify the construction of RevertOptions

Passing default values like address(0) and empty bytes for abortAddress and revertMessage may lead to unintended behaviors depending on the gateway's implementation. Ensure that these default values align with the expected handling in the IGatewayEVM contract.

Run the following script to check the usage of RevertOptions and confirm that default values are acceptable:

✅ Verification successful

Let's analyze the interface definition and RevertOptions structure to understand how these default values are handled.


Default RevertOptions values are safely used in this context

The verification shows that the default values for RevertOptions are consistently used across the codebase:

  • The RevertOptions struct is well-defined with clear fields for handling revert scenarios
  • The default values (address(0), false, empty bytes, and 0) are consistently used in all gateway interaction methods: deposit, depositAndCall, and call
  • The pattern of using msg.sender as the revertAddress while keeping other fields as default values is a standard implementation across the contract
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify how RevertOptions with default values are handled in IGatewayEVM implementations.

# Search for implementations of IGatewayEVM to review how RevertOptions are used.
fd -e sol 'IGatewayEVM' --exec cat {} \; | rg 'function\s+(deposit|depositAndCall|call)\(' -A 10

Length of output: 99


Script:

#!/bin/bash
# Let's try a different approach to find the interface and its implementations
# First, find the interface definition
rg -l "interface IGatewayEVM" 

# Then search for RevertOptions struct definition and usage
rg "struct RevertOptions" -A 5

# Also search for deposit function signatures with RevertOptions
rg "function deposit.*RevertOptions"

Length of output: 4119


Script:

#!/bin/bash
# Search for any validation or checks related to RevertOptions
rg "RevertOptions.*address\(0\)" -B 2 -A 2

# Look for any require statements or validation logic around these parameters
rg "require.*RevertOptions" -B 2 -A 2

Length of output: 4560

Comment on lines +16 to 19
if errorMsg != "" &&
(newStatus == CctxStatus_Aborted || newStatus == CctxStatus_Reverted || newStatus == CctxStatus_PendingRevert) {
m.UpdateErrorMessage(errorMsg)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Error message handling needs additional test coverage

Based on the test coverage analysis:

  • The status transitions are well-tested in status_test.go
  • However, there's insufficient test coverage for the new empty error message guard condition
  • No explicit test cases found for error message handling with Aborted/Reverted/PendingRevert statuses
  • Add test cases in x/crosschain/types/status_test.go to verify:
    • Empty error message is not set for Aborted status
    • Empty error message is not set for Reverted status
    • Empty error message is not set for PendingRevert status
    • Non-empty error messages are correctly set for these statuses
🔗 Analysis chain

LGTM! Verify error message handling in tests.

The additional check for non-empty error messages is a good improvement that prevents setting empty error messages. The status conditions are maintained correctly.

Let's verify the error message handling in tests:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check test coverage for error message scenarios

# Look for test cases covering error message handling
rg -A 5 "UpdateStatusAndErrorMessages.*\"\"" "**/*_test.go"

# Check for test cases with specific status transitions
ast-grep --pattern 'func Test$_(t *testing.T) {
  $$$
  UpdateStatusAndErrorMessages($_, $_, $_)
  $$$
}'

Length of output: 220


Script:

#!/bin/bash
# Let's try a different approach to find test files and error message handling

# Find test files in the crosschain directory
fd "_test.go" x/crosschain

# Look for test cases with UpdateStatusAndErrorMessages
rg -l "UpdateStatusAndErrorMessages" $(fd "_test.go" x/crosschain)

# Check the content of test files for error message scenarios
rg -A 10 "UpdateStatusAndErrorMessages" $(fd "_test.go" x/crosschain)

Length of output: 11923


Script:

#!/bin/bash
# Let's check the status_test.go file specifically for error message tests
rg -A 10 "TestStatus.*" x/crosschain/types/status_test.go

# Also check for any test cases in cctx_test.go that might test error messages
rg -A 10 "UpdateStatusAndErrorMessages|UpdateErrorMessage" x/crosschain/types/cctx_test.go

# Look for test cases with error messages in the keeper tests
rg -A 10 "UpdateStatusAndErrorMessages.*CctxStatus_(Aborted|Reverted|PendingRevert)" x/crosschain/keeper/

Length of output: 1559

@@ -84,5 +89,5 @@
}
}

return fmt.Errorf("no gateway event found in inbound tracker %s", tx.Hash)
return errEventNotFound
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

🛠️ Refactor suggestion

Add test coverage for ProcessInboundTrackerV2 error case

The error case in ProcessInboundTrackerV2 where no gateway events are found lacks test coverage. This error path should be tested to ensure robust error handling. Consider adding the following test cases:

  • Test ProcessInboundTrackerV2 with empty logs to verify errEventNotFound is returned
  • Test ProcessInboundTrackerV2 with invalid/non-matching events to verify error handling
🔗 Analysis chain

Add test coverage for the error case

While using the predefined error is good practice, this error path lacks test coverage. Consider adding a test case where no gateway events are found in the logs.


Let me search for test files and error cases to better understand the test coverage situation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing error case tests
rg -A 5 "errEventNotFound" test/

Length of output: 78


Script:

#!/bin/bash
# Search for test files and error cases in the entire codebase
fd ".*_test.go" | xargs rg -A 5 "errEventNotFound"

# Find the error definition to understand its usage
rg "var errEventNotFound" 

# Search for test files in the same directory as the source file
fd ".*_test.go" zetaclient/chains/evm/observer/

Length of output: 506


Script:

#!/bin/bash
# Check the v2_inbound_tracker.go file to understand the context of errEventNotFound
rg -B 5 -A 5 "errEventNotFound =" zetaclient/chains/evm/observer/v2_inbound_tracker.go

# Look for any test files that might be testing v2_inbound_tracker functionality
rg -l "v2_inbound_tracker" zetaclient/chains/evm/observer/*_test.go

# Search for any test functions related to inbound tracking in v2
rg "func.*Test.*Inbound.*V2" zetaclient/chains/evm/observer/

Length of output: 801

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 92-92: zetaclient/chains/evm/observer/v2_inbound_tracker.go#L92
Added line #L92 was not covered by tests

@@ -28,7 +33,7 @@
}

for _, log := range receipt.Logs {
if log == nil {
if log == nil && log.Address != gatewayAddr {
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

Critical: Fix nil pointer dereference and add test coverage

The condition if log == nil && log.Address != gatewayAddr will cause a panic due to attempting to access log.Address after confirming log is nil. This needs to be fixed and properly tested.

  • Change the condition to use logical OR:
-		if log == nil && log.Address != gatewayAddr {
+		if log == nil || log.Address != gatewayAddr {
  • Add test coverage for nil log handling in zetaclient/chains/evm/observer/inbound_test.go
🔗 Analysis chain

Critical: Fix nil pointer dereference in log check

The current condition if log == nil && log.Address != gatewayAddr will cause a panic when log is nil, as it attempts to access log.Address after checking that log is nil.

Apply this fix:

-		if log == nil && log.Address != gatewayAddr {
+		if log == nil || log.Address != gatewayAddr {

Additionally, this line needs test coverage:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for existing tests of this condition
rg -A 5 "ProcessInboundTrackerV2.*nil.*log" test/

Length of output: 97


Script:

#!/bin/bash
# Let's first check if the file exists and see its content around the problematic line
rg -A 5 -B 5 "if log == nil && log.Address != gatewayAddr" .

# Let's also search for test files related to inbound tracker
fd "inbound.*test.*go$"

# Search for any test files containing "tracker" in their name
fd "tracker.*test.*go$"

Length of output: 2409


Script:

#!/bin/bash
# Let's check the specific EVM inbound test file for any test cases related to nil logs
rg -A 5 "nil.*log" zetaclient/chains/evm/observer/inbound_test.go

# Let's also check the v2 inbound tracker implementation for context
rg -A 10 "func.*ProcessInboundTrackerV2" zetaclient/chains/evm/observer/v2_inbound_tracker.go

Length of output: 705

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 36-36: zetaclient/chains/evm/observer/v2_inbound_tracker.go#L36
Added line #L36 was not covered by tests

Comment on lines +184 to +187
function gatewayCall(address dst, bytes calldata payload) external {
require(!isZetaChain);
IGatewayEVM(gateway).call(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0));
}
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

Validate inputs in gatewayCall function

For robustness, validate the dst address and ensure the payload is not empty before proceeding with the call.

Apply this diff for enhanced validation:

 function gatewayCall(address dst, bytes calldata payload) external {
     require(!isZetaChain);
+    require(dst != address(0), "Invalid destination address");
+    require(payload.length > 0, "Payload cannot be empty");
     IGatewayEVM(gateway).call(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0));
 }
📝 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 gatewayCall(address dst, bytes calldata payload) external {
require(!isZetaChain);
IGatewayEVM(gateway).call(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0));
}
function gatewayCall(address dst, bytes calldata payload) external {
require(!isZetaChain);
require(dst != address(0), "Invalid destination address");
require(payload.length > 0, "Payload cannot be empty");
IGatewayEVM(gateway).call(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0));
}

Comment on lines +171 to +175
// deposit through Gateway EVM
function gatewayDeposit(address dst) external payable {
require(!isZetaChain);
IGatewayEVM(gateway).deposit{value: msg.value}(dst, RevertOptions(msg.sender, false, address(0), "", 0));
}
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

Validate the dst address in gatewayDeposit function

To prevent potential issues, add a check to ensure that the dst (destination) address is not the zero address. This adds a layer of safety against inadvertent misuse.

Apply this diff to include the validation:

 function gatewayDeposit(address dst) external payable {
     require(!isZetaChain);
+    require(dst != address(0), "Invalid destination address");
     IGatewayEVM(gateway).deposit{value: msg.value}(dst, RevertOptions(msg.sender, false, address(0), "", 0));
 }
📝 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
// deposit through Gateway EVM
function gatewayDeposit(address dst) external payable {
require(!isZetaChain);
IGatewayEVM(gateway).deposit{value: msg.value}(dst, RevertOptions(msg.sender, false, address(0), "", 0));
}
// deposit through Gateway EVM
function gatewayDeposit(address dst) external payable {
require(!isZetaChain);
require(dst != address(0), "Invalid destination address");
IGatewayEVM(gateway).deposit{value: msg.value}(dst, RevertOptions(msg.sender, false, address(0), "", 0));
}

Comment on lines +178 to +181
function gatewayDepositAndCall(address dst, bytes calldata payload) external payable {
require(!isZetaChain);
IGatewayEVM(gateway).depositAndCall{value: msg.value}(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0));
}
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 gatewayDepositAndCall parameters

Similar to gatewayDeposit, ensure that the dst address is validated and that the payload is not empty to prevent unintended calls.

Apply this diff to include validations:

 function gatewayDepositAndCall(address dst, bytes calldata payload) external payable {
     require(!isZetaChain);
+    require(dst != address(0), "Invalid destination address");
+    require(payload.length > 0, "Payload cannot be empty");
     IGatewayEVM(gateway).depositAndCall{value: msg.value}(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0));
 }
📝 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 gatewayDepositAndCall(address dst, bytes calldata payload) external payable {
require(!isZetaChain);
IGatewayEVM(gateway).depositAndCall{value: msg.value}(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0));
}
function gatewayDepositAndCall(address dst, bytes calldata payload) external payable {
require(!isZetaChain);
require(dst != address(0), "Invalid destination address");
require(payload.length > 0, "Payload cannot be empty");
IGatewayEVM(gateway).depositAndCall{value: msg.value}(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0));
}

Comment on lines +153 to +162
if err == nil && tx != nil {
// filter error if event is not found, in this case we run v1 tracker process
if err := ob.ProcessInboundTrackerV2(ctx, gateway, gatewayAddr, tx, receipt); err != nil &&
!errors.Is(err, errEventNotFound) {
return err
} else if err == nil {
// continue with next tracker
continue
}
} else {
// check and vote on inbound tx
switch tracker.CoinType {
case coin.CoinType_Zeta:
_, err = ob.CheckAndVoteInboundTokenZeta(ctx, tx, receipt, true)
case coin.CoinType_ERC20:
_, err = ob.CheckAndVoteInboundTokenERC20(ctx, tx, receipt, true)
case coin.CoinType_Gas:
_, err = ob.CheckAndVoteInboundTokenGas(ctx, tx, receipt, true)
default:
return fmt.Errorf(
"unknown coin type %s for inbound %s chain %d",
tracker.CoinType,
tx.Hash,
ob.Chain().ChainId,
)
}
if err != nil {
return errors.Wrapf(err, "error checking and voting for inbound %s chain %d", tx.Hash, ob.Chain().ChainId)
}
}
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

Avoid variable shadowing to enhance code clarity

The variable err is being redeclared in the inner if statement, which shadows the outer err. This can lead to confusion and potential errors. It's recommended to rename the inner err variable or restructure the code to prevent shadowing.

Apply this diff to prevent variable shadowing:

 if err == nil && tx != nil {
 	// filter error if event is not found, in this case we run v1 tracker process
-	if err := ob.ProcessInboundTrackerV2(ctx, gateway, gatewayAddr, tx, receipt); err != nil &&
+	processErr := ob.ProcessInboundTrackerV2(ctx, gateway, gatewayAddr, tx, receipt)
+	if processErr != nil && !errors.Is(processErr, errEventNotFound) {
 		return processErr
-	} else if err == nil {
+	} else if processErr == nil {
 		// continue with next tracker
 		continue
 	}
 }
📝 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
if err == nil && tx != nil {
// filter error if event is not found, in this case we run v1 tracker process
if err := ob.ProcessInboundTrackerV2(ctx, gateway, gatewayAddr, tx, receipt); err != nil &&
!errors.Is(err, errEventNotFound) {
return err
} else if err == nil {
// continue with next tracker
continue
}
} else {
// check and vote on inbound tx
switch tracker.CoinType {
case coin.CoinType_Zeta:
_, err = ob.CheckAndVoteInboundTokenZeta(ctx, tx, receipt, true)
case coin.CoinType_ERC20:
_, err = ob.CheckAndVoteInboundTokenERC20(ctx, tx, receipt, true)
case coin.CoinType_Gas:
_, err = ob.CheckAndVoteInboundTokenGas(ctx, tx, receipt, true)
default:
return fmt.Errorf(
"unknown coin type %s for inbound %s chain %d",
tracker.CoinType,
tx.Hash,
ob.Chain().ChainId,
)
}
if err != nil {
return errors.Wrapf(err, "error checking and voting for inbound %s chain %d", tx.Hash, ob.Chain().ChainId)
}
}
if err == nil && tx != nil {
// filter error if event is not found, in this case we run v1 tracker process
processErr := ob.ProcessInboundTrackerV2(ctx, gateway, gatewayAddr, tx, receipt)
if processErr != nil && !errors.Is(processErr, errEventNotFound) {
return processErr
} else if processErr == nil {
// continue with next tracker
continue
}
}
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 153-156: zetaclient/chains/evm/observer/inbound.go#L153-L156
Added lines #L153 - L156 were not covered by tests


[warning] 158-160: zetaclient/chains/evm/observer/inbound.go#L158-L160
Added lines #L158 - L160 were not covered by tests

Comment on lines +321 to +327
func (_TestDAppV2 *TestDAppV2Caller) Gateway(opts *bind.CallOpts) (common.Address, error) {
var out []interface{}
err := _TestDAppV2.contract.Call(opts, &out, "gateway")

if err != nil {
return *new(common.Address), err
}
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

Increase test coverage for the Gateway method

The newly added Gateway method and its session variants are not currently covered by tests. Adding unit tests for these methods will ensure they function as intended and improve overall code reliability.

Also applies to: 329-331, 338-339, 345-346

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 321-327: pkg/contracts/testdappv2/TestDAppV2.go#L321-L327
Added lines #L321 - L327 were not covered by tests

Comment on lines +549 to +550
func (_TestDAppV2 *TestDAppV2Transactor) GatewayCall(opts *bind.TransactOpts, dst common.Address, payload []byte) (*types.Transaction, error) {
return _TestDAppV2.contract.Transact(opts, "gatewayCall", dst, payload)
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

Add unit tests for new gateway-related methods

The methods GatewayCall, GatewayDeposit, and GatewayDepositAndCall, along with their session variants, lack test coverage. Implementing unit tests for these methods will help verify their behavior and ensure code robustness.

Also applies to: 556-557, 563-564, 570-571, 577-578, 584-585, 591-592, 598-599, 605-606

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 549-550: pkg/contracts/testdappv2/TestDAppV2.go#L549-L550
Added lines #L549 - L550 were not covered by tests

@@ -13,7 +13,8 @@ func (m *Status) AbortRefunded() {
func (m *Status) UpdateStatusAndErrorMessages(newStatus CctxStatus, statusMsg, errorMsg string) {
m.UpdateStatus(newStatus, statusMsg)

if newStatus == CctxStatus_Aborted || newStatus == CctxStatus_Reverted || newStatus == CctxStatus_PendingRevert {
if errorMsg != "" &&
(newStatus == CctxStatus_Aborted || newStatus == CctxStatus_Reverted || newStatus == CctxStatus_PendingRevert) {
Copy link
Contributor

Choose a reason for hiding this comment

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

can we move status check to a function w/ a comment? It's not clear why only these statuses are eligible

Copy link
Contributor

Choose a reason for hiding this comment

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

+1

ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/onrik/ethrpc"
"github.com/zeta-chain/protocol-contracts/v2/pkg/gatewayevm.sol"

"github.com/zeta-chain/node/zetaclient/zetacore"
)

var errEventNotFound = errors.New("no gateway event found in inbound tracker")
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
var errEventNotFound = errors.New("no gateway event found in inbound tracker")
var ErrEventNotFound = errors.New("event not found")

@@ -28,7 +33,7 @@ func (ob *Observer) ProcessInboundTrackerV2(
}

for _, log := range receipt.Logs {
if log == nil {
if log == nil && log.Address != gatewayAddr {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this a typo?

Choose a reason for hiding this comment

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

+1

// ProcessInboundTrackerV2 processes inbound tracker events from the gateway
func (ob *Observer) ProcessInboundTrackerV2(
ctx context.Context,
gateway *gatewayevm.GatewayEVM,
gatewayAddr ethcommon.Address,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to pass gateway and gatewayAddr into this function? It should be within *Observer

@@ -84,5 +89,5 @@ func (ob *Observer) ProcessInboundTrackerV2(
}
}

return fmt.Errorf("no gateway event found in inbound tracker %s", tx.Hash)
return errEventNotFound
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return errEventNotFound
return errors.Wrapf(ErrEventNotFound, "inbound tracker %s", tx.Hash)

gatewayAddr, gateway, err := ob.GetGatewayContract()
if err != nil {
ob.Logger().Inbound.Debug().Err(err).Msg("error getting gateway contract for processing inbound tracker")
}
if err == nil && tx != nil && ethcommon.HexToAddress(tx.To) == gatewayAddr {
if err := ob.ProcessInboundTrackerV2(ctx, gateway, tx, receipt); err != nil {
if err == nil && tx != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can tx be nil? If no, let's remove this check, otherwise tx == nil case should be handled above

Choose a reason for hiding this comment

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

I've double-checked it and it is validated in TransactionByHash() by calling `ValidateEvmTransaction():

func ValidateEvmTransaction(tx *ethrpc.Transaction) error {
if tx == nil {
return fmt.Errorf("transaction is nil")
}

This check here can be safely removed.

@berndartmueller
Copy link

My comment in #3179 (comment) is now relevant.

In this new version, a tx might contain multiple logs emitted by the gateway if the caller contract interacted repeatedly with the gateway contract. Therefore, ProcessInboundTrackerV2() should process all logs that have been emitted by the gateway (i.e., log.Address == gatewayAddr) instead of returning immediately after posting the inbound vote here

and here

and here

or in the case where the event is not processable

return fmt.Errorf("event from inbound tracker %s is not processable", tx.Hash)

return fmt.Errorf("event from inbound tracker %s is not processable", tx.Hash)

return fmt.Errorf("event from inbound tracker %s is not processable", tx.Hash)

@@ -240,7 +240,7 @@ func (k Keeper) processSuccessfulOutbound(
oldStatus := cctx.CctxStatus.Status
switch oldStatus {
case types.CctxStatus_PendingRevert:
cctx.SetReverted("", "revert executed")
cctx.SetReverted("", "")
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider adding the value to status message instead

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-changelog Skip changelog CI check V2_TESTS Run make start-v2-test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow adding inbound tracker for v2 inbounds created through smart contracts
4 participants