-
Notifications
You must be signed in to change notification settings - Fork 109
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
base: develop
Are you sure you want to change the base?
Changes from 5 commits
7b856c7
be1179b
93efb98
8d5caac
c35c086
4cd508d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,6 +1,26 @@ | ||||||||||||||||||||||
// SPDX-License-Identifier: MIT | ||||||||||||||||||||||
pragma solidity ^0.8.26; | ||||||||||||||||||||||
|
||||||||||||||||||||||
struct RevertOptions { | ||||||||||||||||||||||
address revertAddress; | ||||||||||||||||||||||
bool callOnRevert; | ||||||||||||||||||||||
address abortAddress; | ||||||||||||||||||||||
bytes revertMessage; | ||||||||||||||||||||||
uint256 onRevertGasLimit; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
interface IGatewayEVM { | ||||||||||||||||||||||
function deposit(address receiver, RevertOptions calldata revertOptions) external payable; | ||||||||||||||||||||||
function depositAndCall( | ||||||||||||||||||||||
address receiver, | ||||||||||||||||||||||
bytes calldata payload, | ||||||||||||||||||||||
RevertOptions calldata revertOptions | ||||||||||||||||||||||
) | ||||||||||||||||||||||
external | ||||||||||||||||||||||
payable; | ||||||||||||||||||||||
function call(address receiver, bytes calldata payload, RevertOptions calldata revertOptions) external; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
interface IERC20 { | ||||||||||||||||||||||
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
@@ -14,6 +34,9 @@ contract TestDAppV2 { | |||||||||||||||||||||
// define if the chain is ZetaChain | ||||||||||||||||||||||
bool immutable public isZetaChain; | ||||||||||||||||||||||
|
||||||||||||||||||||||
// address of the gateway | ||||||||||||||||||||||
address immutable public gateway; | ||||||||||||||||||||||
|
||||||||||||||||||||||
struct zContext { | ||||||||||||||||||||||
bytes origin; | ||||||||||||||||||||||
address sender; | ||||||||||||||||||||||
|
@@ -44,8 +67,9 @@ contract TestDAppV2 { | |||||||||||||||||||||
mapping(bytes32 => uint256) public amountWithMessage; | ||||||||||||||||||||||
|
||||||||||||||||||||||
// the constructor is used to determine if the chain is ZetaChain | ||||||||||||||||||||||
constructor(bool isZetaChain_) { | ||||||||||||||||||||||
constructor(bool isZetaChain_, address gateway_) { | ||||||||||||||||||||||
isZetaChain = isZetaChain_; | ||||||||||||||||||||||
gateway = gateway_; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// return the index used for the "WithMessage" mapping when the message for calls is empty | ||||||||||||||||||||||
|
@@ -144,6 +168,24 @@ contract TestDAppV2 { | |||||||||||||||||||||
return ""; | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
// 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 and call through Gateway EVM | ||||||||||||||||||||||
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)); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+178
to
+181
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add validation for Similar to 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
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
// call through Gateway EVM | ||||||||||||||||||||||
function gatewayCall(address dst, bytes calldata payload) external { | ||||||||||||||||||||||
require(!isZetaChain); | ||||||||||||||||||||||
IGatewayEVM(gateway).call(dst, payload, RevertOptions(msg.sender, false, address(0), "", 0)); | ||||||||||||||||||||||
} | ||||||||||||||||||||||
Comment on lines
+184
to
+187
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate inputs in For robustness, validate the 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
Suggested change
|
||||||||||||||||||||||
|
||||||||||||||||||||||
function consumeGas() internal { | ||||||||||||||||||||||
// Approximate target gas consumption | ||||||||||||||||||||||
uint256 targetGas = 500000; | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -240,7 +240,7 @@ func (k Keeper) processSuccessfulOutbound( | |
oldStatus := cctx.CctxStatus.Status | ||
switch oldStatus { | ||
case types.CctxStatus_PendingRevert: | ||
cctx.SetReverted("", "revert executed") | ||
cctx.SetReverted("", "") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding the value to status message instead |
||
case types.CctxStatus_PendingOutbound: | ||
cctx.SetOutboundMined("") | ||
default: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 |
||
m.UpdateErrorMessage(errorMsg) | ||
} | ||
Comment on lines
+16
to
19
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
🔗 Analysis chainLGTM! 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 executedThe 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 |
||
} | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -145,35 +145,40 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ob.Logger().Inbound.Info().Msgf("checking tracker for inbound %s chain %d", tracker.TxHash, ob.Chain().ChainId) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// if the transaction is sent to the gateway, this is a v2 inbound | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// try processing the tracker for v2 inbound | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've double-checked it and it is validated in node/zetaclient/chains/evm/validation.go Lines 34 to 37 in 4cd508d
This check here can be safely removed. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// 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) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+153
to
+162
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Avoid variable shadowing to enhance code clarity The variable 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
Suggested change
🧰 Tools🪛 GitHub Check: codecov/patch[warning] 153-156: zetaclient/chains/evm/observer/inbound.go#L153-L156 [warning] 158-160: zetaclient/chains/evm/observer/inbound.go#L158-L160 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// try processing the tracker for v1 inbound | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -2,19 +2,24 @@ | |||||
|
||||||
import ( | ||||||
"context" | ||||||
"errors" | ||||||
"fmt" | ||||||
|
||||||
ethcommon "github.com/ethereum/go-ethereum/common" | ||||||
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") | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
|
||||||
// ProcessInboundTrackerV2 processes inbound tracker events from the gateway | ||||||
func (ob *Observer) ProcessInboundTrackerV2( | ||||||
ctx context.Context, | ||||||
gateway *gatewayevm.GatewayEVM, | ||||||
gatewayAddr ethcommon.Address, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to pass |
||||||
tx *ethrpc.Transaction, | ||||||
receipt *ethtypes.Receipt, | ||||||
) error { | ||||||
|
@@ -28,7 +33,7 @@ | |||||
} | ||||||
|
||||||
for _, log := range receipt.Logs { | ||||||
if log == nil { | ||||||
if log == nil && log.Address != gatewayAddr { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Critical: Fix nil pointer dereference and add test coverage The condition
- if log == nil && log.Address != gatewayAddr {
+ if log == nil || log.Address != gatewayAddr {
🔗 Analysis chainCritical: Fix nil pointer dereference in log check The current condition Apply this fix: - if log == nil && log.Address != gatewayAddr {
+ if log == nil || log.Address != gatewayAddr { Additionally, this line needs test coverage: 🏁 Scripts executedThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a typo? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 |
||||||
continue | ||||||
} | ||||||
|
||||||
|
@@ -84,5 +89,5 @@ | |||||
} | ||||||
} | ||||||
|
||||||
return fmt.Errorf("no gateway event found in inbound tracker %s", tx.Hash) | ||||||
return errEventNotFound | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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:
🔗 Analysis chainAdd 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 executedThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Validate the
dst
address ingatewayDeposit
functionTo 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