Skip to content

Conversation

@s2imonovic
Copy link
Collaborator

@s2imonovic s2imonovic commented Oct 14, 2025

Implement validation libraries for common checks.

Summary by CodeRabbit

  • New Features

    • Added public getters for limits in ZEVM: max message size, min/max gas limit, and max revert gas limit.
    • Centralized validation improves input checks and clearer errors across EVM and ZEVM.
  • Refactor

    • Standardized and parameterized errors (e.g., approval failures, whitelist, payload/message size, insufficient amount).
    • API change: ZEVM depositAndCall now requires an explicit token address.
    • Safer token operations via wrapped transfers, burns, and deposits.
  • Tests

    • Updated expectations to new error names, parameters, and selectors, including unified insufficient amount and detailed size/approval errors.

@s2imonovic s2imonovic requested review from a team as code owners October 14, 2025 20:06
@github-actions github-actions bot added the feat label Oct 14, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 14, 2025

📝 Walkthrough

Walkthrough

Centralizes input validation by introducing GatewayEVMValidations and GatewayZEVMValidations libraries; updates GatewayEVM and GatewayZEVM to use them. Enhances error types with contextual parameters, adds revert gas limit constant and error, adjusts ZEVM public API and adds getters, and updates tests to new error signatures and validation paths.

Changes

Cohort / File(s) Summary of Changes
Revert config
contracts/Revert.sol
Added MAX_REVERT_GAS_LIMIT constant (2_000_000) and RevertGasLimitExceeded(provided, maximum) error.
EVM validations library
contracts/evm/libraries/GatewayEVMValidations.sol
New library with MAX_PAYLOAD_SIZE and internal validators for addresses, amounts, payload size, revert options, and composite param checks (deposit/call).
ZEVM validations library
contracts/zevm/libraries/GatewayZEVMValidations.sol
New library defining message/gas limits and internal validators for addresses, amounts, gas limits, targets, message/revert options, and composite flows (withdraw/deposit/execute).
EVM gateway refactor
contracts/evm/GatewayEVM.sol
Imports and uses GatewayEVMValidations; replaces inline checks with validation calls; updates revert errors to parameterized forms; minor control-flow adjustments to route via validators.
EVM interfaces (errors)
contracts/evm/interfaces/IGatewayEVM.sol
Consolidated InsufficientETH/ERC20 into InsufficientEVMAmount; parameterized ApprovalFailed(token, spender), NotWhitelistedInCustody(token), PayloadSizeExceeded(provided, maximum).
ZEVM gateway refactor + getters
contracts/zevm/GatewayZEVM.sol
Uses GatewayZEVMValidations; removes inline constants; adds safe IZRC20 helpers; replaces direct calls with safe wrappers; parameterizes errors; adds getters: getMaxMessageSize/MinGasLimit/MaxGasLimit/MaxRevertGasLimit.
ZEVM interfaces (errors + API)
contracts/zevm/interfaces/IGatewayZEVM.sol
Added EmptyAddress; unified Insufficient* into InsufficientAmount; parameterized several ZRC20 errors and MessageSizeExceeded; renamed InsufficientGasLimit to InvalidGasLimit; modified depositAndCall to include zrc20 param.
EVM tests
test/ERC20Custody.t.sol, test/GatewayEVM.t.sol
Updated expected revert selectors/encodings: InsufficientEVMAmount; parameterized NotWhitelistedInCustody and PayloadSizeExceeded assertions.
ZEVM tests
test/GatewayZEVM.t.sol
Switched to EmptyAddress, InsufficientAmount, InvalidGasLimit; use getMaxMessageSize(); parameterized MessageSizeExceeded and ZRC20TransferFailed; removed local ZeroAddress error.
Upgrade test helpers (EVM)
test/utils/upgrades/GatewayEVMUpgradeTest.sol
Uses GatewayEVMValidations; adds nonReentrant to multiple funcs; reworks approval logic for non-standard ERC20s; updates errors to parameterized forms.
Upgrade test helpers (ZEVM)
test/utils/upgrades/GatewayZEVMUpgradeTest.sol
Integrates GatewayZEVMValidations; adds safe IZRC20 helpers; adds zetaToken var; adds getters and executeAbort; restructures withdraw/deposit paths; marks ZETA flows not supported; broad validation adoption.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant GatewayEVM
  participant Validations as GatewayEVMValidations
  Note over User,GatewayEVM: EVM deposit/depositAndCall
  User->>GatewayEVM: deposit/depositAndCall(params, revertOptions)
  GatewayEVM->>Validations: validateDeposit(…)/validateDepositAndCall(…)
  Validations-->>GatewayEVM: ok or revert (InsufficientEVMAmount, PayloadSizeExceeded, RevertGasLimitExceeded, ZeroAddress)
  alt validation ok
    GatewayEVM->>GatewayEVM: proceed with custody/allowance
    GatewayEVM-->>User: emit events / success
  else validation failed
    GatewayEVM-->>User: revert with parameterized error
  end
Loading
sequenceDiagram
  autonumber
  actor User
  participant GatewayZEVM
  participant Valid as GatewayZEVMValidations
  participant ZRC20 as IZRC20 Token
  Note over User,GatewayZEVM: ZEVM withdraw/deposit/call
  User->>GatewayZEVM: withdraw/deposit/execute(…)
  GatewayZEVM->>Valid: validate*(receiver/amount/gas/message/revertOptions)
  Valid-->>GatewayZEVM: ok or revert (EmptyAddress, InsufficientAmount, InvalidGasLimit, MessageSizeExceeded, RevertGasLimitExceeded)
  alt withdraw path
    GatewayZEVM->>ZRC20: _safeTransferFrom/_safeBurn
    ZRC20-->>GatewayZEVM: success=false? (caught)
    alt failure
      GatewayZEVM-->>User: revert ZRC20TransferFailed/ZRC20BurnFailed(zrc20, …)
    else success
      GatewayZEVM-->>User: emit Withdrawn/… and return
    end
  else deposit/execute path
    GatewayZEVM->>ZRC20: _safeDeposit / other
    ZRC20-->>GatewayZEVM: success flag
    alt failure
      GatewayZEVM-->>User: revert ZRC20DepositFailed(zrc20, …)
    else success
      GatewayZEVM-->>User: emit events / success
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

refactor

Suggested reviewers

  • lumtis
  • skosito

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title follows a conventional commit style and concisely describes the primary enhancement of adding validation libraries, which aligns directly with the introduction of GatewayEVMValidations and GatewayZEVMValidations throughout the changeset. It is clear and specific enough that a reviewer quickly understands the PR’s main purpose without extra noise.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/validations-libraries

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
contracts/zevm/GatewayZEVM.sol (4)

171-195: Validate zrc20 is non-zero in withdraw (ZRC20)

Callers can pass address(0), leading to a low-level call failure when reading GAS_LIMIT(). Validate early to return EmptyAddress.

 function withdraw(
   bytes memory receiver,
   uint256 amount,
   address zrc20,
   RevertOptions calldata revertOptions
 )
   external
   whenNotPaused
 {
-  GatewayZEVMValidations.validateWithdrawalParams(receiver, amount, revertOptions);
+  GatewayZEVMValidations.validateNonZeroAddress(zrc20);
+  GatewayZEVMValidations.validateWithdrawalParams(receiver, amount, revertOptions);

205-231: Validate zrc20 is non-zero in withdraw (custom gas limit)

Same as above; prevent ambiguous low-level failures.

 {
-  GatewayZEVMValidations.validateWithdrawalParams(receiver, amount, revertOptions);
+  GatewayZEVMValidations.validateNonZeroAddress(zrc20);
+  GatewayZEVMValidations.validateWithdrawalParams(receiver, amount, revertOptions);
   GatewayZEVMValidations.validateGasLimit(gasLimit);

240-266: Validate zrc20 is non-zero in withdrawAndCall

Ensure explicit EmptyAddress error before IZRC20 calls.

 {
-  GatewayZEVMValidations.validateWithdrawalAndCallParams(receiver, amount, message, callOptions, revertOptions);
+  GatewayZEVMValidations.validateNonZeroAddress(zrc20);
+  GatewayZEVMValidations.validateWithdrawalAndCallParams(receiver, amount, message, callOptions, revertOptions);

347-359: Validate zrc20 is non-zero in call

Call uses zrc20 to compute fees; add non-zero validation to avoid low-level revert on interfaces.

 function call(
   bytes memory receiver,
   address zrc20,
   bytes calldata message,
   CallOptions calldata callOptions,
   RevertOptions calldata revertOptions
 )
   external
   whenNotPaused
 {
+  GatewayZEVMValidations.validateNonZeroAddress(zrc20);
   GatewayZEVMValidations.validateCallAndRevertOptions(callOptions, revertOptions, message.length);
   _call(receiver, zrc20, message, callOptions, revertOptions);
 }
🧹 Nitpick comments (17)
contracts/Revert.sol (1)

4-11: Introduce MAX_REVERT_GAS_LIMIT and RevertGasLimitExceeded

Good addition. Consider exposing the max via a common validation utility or a getter to avoid divergence across modules consuming this constant in the future.

contracts/evm/GatewayEVM.sol (4)

181-199: Validate token address in executeWithERC20

Add a non-zero (and ideally contract code) check for token to fail fast on bad inputs.

Apply this diff:

 function executeWithERC20(
   MessageContext calldata messageContext,
   address token,
   address to,
   uint256 amount,
   bytes calldata data
 ) 
   public
   nonReentrant
   onlyRole(ASSET_HANDLER_ROLE)
   whenNotPaused
 {
-  GatewayEVMValidations.validateAmount(amount);
-  GatewayEVMValidations.validateNonZeroAddress(to);
+  GatewayEVMValidations.validateAmount(amount);
+  GatewayEVMValidations.validateNonZeroAddress(to);
+  GatewayEVMValidations.validateNonZeroAddress(token);
   // Approve the target contract to spend the tokens
   if (!_resetApproval(token, to)) revert ApprovalFailed(token, to);
   IERC20(token).forceApprove(to, amount);
   ...
 }

227-234: Validate token address in revertWithERC20

Mirror executeWithERC20: validate token is non-zero (and ideally a contract).

Apply this diff:

 function revertWithERC20(
   address token,
   address to,
   uint256 amount,
   bytes calldata data,
   RevertContext calldata revertContext
 ) 
   external
   nonReentrant
   onlyRole(ASSET_HANDLER_ROLE)
   whenNotPaused
 {
-  GatewayEVMValidations.validateAmount(amount);
-  GatewayEVMValidations.validateNonZeroAddress(to);
+  GatewayEVMValidations.validateAmount(amount);
+  GatewayEVMValidations.validateNonZeroAddress(to);
+  GatewayEVMValidations.validateNonZeroAddress(token);
   IERC20(token).safeTransfer(address(to), amount);
   Revertable(to).onRevert(revertContext);
 }

412-419: Use SafeERC20.forceApprove for zetaConnector approvals

Direct IERC20.approve can break on non-standard tokens; use SafeERC20.forceApprove for consistency.

Apply this diff:

- if (!IERC20(token).approve(zetaConnector, amount)) revert ApprovalFailed(token, zetaConnector);
+ IERC20(token).forceApprove(zetaConnector, amount);

239-247: Add nonReentrant to deposit/depositAndCall/call for parity and safety

Main flows forward ETH/tokens and emit events; adding nonReentrant matches the upgrade test and hardens against future changes.

Apply these diffs:

-function deposit(address receiver, RevertOptions calldata revertOptions) external payable whenNotPaused {
+function deposit(address receiver, RevertOptions calldata revertOptions) external payable nonReentrant whenNotPaused {
-function deposit(
+function deposit(
   address receiver,
   uint256 amount,
   address asset,
   RevertOptions calldata revertOptions
 )
   external
-  whenNotPaused
+  whenNotPaused
+  nonReentrant
 {
-function depositAndCall(
+function depositAndCall(
   address receiver,
   bytes calldata payload,
   RevertOptions calldata revertOptions
 )
   external
   payable
-  whenNotPaused
+  whenNotPaused
+  nonReentrant
 {
-function depositAndCall(
+function depositAndCall(
   address receiver,
   uint256 amount,
   address asset,
   bytes calldata payload,
   RevertOptions calldata revertOptions
 )
   external
-  whenNotPaused
+  whenNotPaused
+  nonReentrant
 {
-function call(
+function call(
   address receiver,
   bytes calldata payload,
   RevertOptions calldata revertOptions
 )
   external
-  whenNotPaused
+  whenNotPaused
+  nonReentrant
 {

Also applies to: 254-268, 274-291, 298-314, 320-330

test/utils/upgrades/GatewayEVMUpgradeTest.sol (3)

185-191: Validate token address in executeWithERC20 (upgrade test)

Add a non-zero check for token similar to to.

Apply this diff:

- GatewayEVMValidations.validateAmount(amount);
- GatewayEVMValidations.validateNonZeroAddress(to);
+ GatewayEVMValidations.validateAmount(amount);
+ GatewayEVMValidations.validateNonZeroAddress(to);
+ GatewayEVMValidations.validateNonZeroAddress(token);

231-233: Validate token address in revertWithERC20 (upgrade test)

Mirror executeWithERC20; validate token not zero.

Apply this diff:

- GatewayEVMValidations.validateAmount(amount);
- GatewayEVMValidations.validateNonZeroAddress(to);
+ GatewayEVMValidations.validateAmount(amount);
+ GatewayEVMValidations.validateNonZeroAddress(to);
+ GatewayEVMValidations.validateNonZeroAddress(token);

427-429: Use SafeERC20.forceApprove for zetaConnector approvals (upgrade test)

Prefer SafeERC20 to handle non-standard tokens.

Apply this diff:

- if (!IERC20(token).approve(zetaConnector, amount)) revert ApprovalFailed(token, zetaConnector);
+ IERC20(token).forceApprove(zetaConnector, amount);
contracts/zevm/libraries/GatewayZEVMValidations.sol (1)

72-90: DRY up revert gas limit check in validateCallAndRevertOptions

You repeat the onRevertGasLimit check here. Prefer reusing validateRevertOptions to keep logic centralized and avoid drift.

Apply:

 function validateCallAndRevertOptions(
   CallOptions calldata callOptions,
   RevertOptions calldata revertOptions,
   uint256 messageLength
 )
   internal
   pure
 {
   validateGasLimit(callOptions.gasLimit);
   validateMessageSize(messageLength, revertOptions.revertMessage.length);
-  if (revertOptions.onRevertGasLimit > MAX_REVERT_GAS_LIMIT) {
-      revert RevertGasLimitExceeded(revertOptions.onRevertGasLimit, MAX_REVERT_GAS_LIMIT);
-  }
+  validateRevertOptions(revertOptions);
 }
test/GatewayZEVM.t.sol (1)

182-188: Tests align with new error selectors and payload sizing — add edge coverage

LGTM on updated selectors, abi-encoded reverts, and dynamic size checks. Please add:

  • Upper-bound gas limit: expect InvalidGasLimit when gasLimit > gateway.getMaxGasLimit().
  • Revert gas limit: expect RevertGasLimitExceeded when revertOptions.onRevertGasLimit > gateway.getMaxRevertGasLimit().
  • ZRC20 address zero for user paths (withdraw/withdrawAndCall/call): expect EmptyAddress once contract adds that validation (see contract comment).

Also applies to: 193-199, 203-211, 255-265, 268-276, 276-286, 288-299, 301-311, 313-337, 339-350, 425-429, 431-441, 443-448, 450-454, 516-525, 547-557, 722-726, 728-736, 738-750

contracts/zevm/GatewayZEVM.sol (2)

115-126: Fix _safeDeposit doc comments

Param docs are mismatched; clarify for maintainability.

-// @notice Helper function to safely deposit
-// @param zrc20 The ZRC20 token address
-// @param amount The target address to receive the deposited tokens
-// @param amount The amount to deposit
-// @return True if the deposit was successful, false otherwise
+/// @notice Helper function to safely deposit ZRC20 tokens
+/// @param zrc20 The ZRC20 token address
+/// @param target The address to receive the deposited tokens
+/// @param amount The amount to deposit
+/// @return True if the deposit was successful, false otherwise

30-31: Remove unused using directive

You call the library with its name; using GatewayZEVMValidations for * is not utilized. Safe to remove.

contracts/evm/libraries/GatewayEVMValidations.sol (1)

27-35: Minor clarity: reuse totalSize variable

Small nit: use totalSize in the conditional for consistency.

 function validatePayloadSize(uint256 payloadLength, uint256 revertMessageLength) internal pure {
     uint256 totalSize = payloadLength + revertMessageLength;
-    if (payloadLength + revertMessageLength > MAX_PAYLOAD_SIZE) {
+    if (totalSize > MAX_PAYLOAD_SIZE) {
         revert IGatewayEVMErrors.PayloadSizeExceeded(totalSize, MAX_PAYLOAD_SIZE);
     }
 }
test/utils/upgrades/GatewayZEVMUpgradeTest.sol (4)

132-137: Fix NatSpec/comments for _safeDeposit parameters.

Param names/descriptions are incorrect/duplicated; use proper order and phrasing.

-// @notice Helper function to safely deposit
-// @param zrc20 The ZRC20 token address
-// @param amount The target address to receive the deposited tokens
-// @param amount The amount to deposit
-// @return True if the deposit was successful, false otherwise
+/// @notice Helper function to safely deposit ZRC20 tokens.
+/// @param zrc20 The ZRC20 token address.
+/// @param target The address to receive the deposited tokens.
+/// @param amount The amount to deposit.
+/// @return success True if the deposit was successful, false otherwise.

33-33: Remove unused using directive.

using GatewayZEVMValidations for *; is unused (all calls are static). Drop it for clarity.

-    using GatewayZEVMValidations for *;

189-212: Add nonReentrant to external flows performing token calls.

withdraw/withdraw (custom gas)/withdrawAndCall (and call) perform external token interactions before completion. Align with other entry points (execute*, depositAnd*) and add nonReentrant.

 function withdraw(
@@
-    external
-    whenNotPaused
+    external
+    nonReentrant
+    whenNotPaused
 ) {
 function withdraw(
@@
-    external
-    whenNotPaused
+    external
+    nonReentrant
+    whenNotPaused
 ) {
 function withdrawAndCall(
@@
-    external
-    whenNotPaused
+    external
+    nonReentrant
+    whenNotPaused
 ) {
 function call(
@@
-    external
-    whenNotPaused
+    external
+    nonReentrant
+    whenNotPaused
 ) {

Also applies to: 223-248, 258-283, 365-376


255-255: Fix typo in NatSpec.

Use “arbitrary”.

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

Also applies to: 362-362

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6b9d7c0 and 4bb38a6.

📒 Files selected for processing (12)
  • contracts/Revert.sol (1 hunks)
  • contracts/evm/GatewayEVM.sol (14 hunks)
  • contracts/evm/interfaces/IGatewayEVM.sol (3 hunks)
  • contracts/evm/libraries/GatewayEVMValidations.sol (1 hunks)
  • contracts/zevm/GatewayZEVM.sol (17 hunks)
  • contracts/zevm/interfaces/IGatewayZEVM.sol (2 hunks)
  • contracts/zevm/libraries/GatewayZEVMValidations.sol (1 hunks)
  • test/ERC20Custody.t.sol (3 hunks)
  • test/GatewayEVM.t.sol (9 hunks)
  • test/GatewayZEVM.t.sol (20 hunks)
  • test/utils/upgrades/GatewayEVMUpgradeTest.sol (14 hunks)
  • test/utils/upgrades/GatewayZEVMUpgradeTest.sol (17 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
contracts/**

⚙️ CodeRabbit configuration file

Review the Solidity contracts for security vulnerabilities and best practices.

Files:

  • contracts/evm/interfaces/IGatewayEVM.sol
  • contracts/evm/libraries/GatewayEVMValidations.sol
  • contracts/zevm/GatewayZEVM.sol
  • contracts/zevm/libraries/GatewayZEVMValidations.sol
  • contracts/zevm/interfaces/IGatewayZEVM.sol
  • contracts/evm/GatewayEVM.sol
  • contracts/Revert.sol
test/**

⚙️ CodeRabbit configuration file

Review the test files for proper coverage, edge cases, and best practices.

Files:

  • test/ERC20Custody.t.sol
  • test/GatewayEVM.t.sol
  • test/GatewayZEVM.t.sol
  • test/utils/upgrades/GatewayZEVMUpgradeTest.sol
  • test/utils/upgrades/GatewayEVMUpgradeTest.sol
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: generate
  • GitHub Check: test
  • GitHub Check: slither
🔇 Additional comments (12)
test/ERC20Custody.t.sol (1)

295-296: Selectors update to InsufficientEVMAmount looks correct

Using InsufficientEVMAmount.selector aligns with the new consolidated error in IGatewayEVMErrors.

Also applies to: 411-412, 560-561

contracts/evm/GatewayEVM.sol (1)

49-51: Ensure MAX_PAYLOAD_SIZE enforcement is single-sourced

Tests read MAX_PAYLOAD_SIZE() from GatewayEVM; confirm GatewayEVMValidations uses the same constant to avoid drift.

Briefly confirm the library derives the max from GatewayEVM (or a common shared source) to prevent inconsistencies between validation and test expectations.

Also applies to: 283-291, 308-314, 327-330

contracts/evm/interfaces/IGatewayEVM.sol (1)

84-86: Interface error updates look consistent with validations

  • InsufficientEVMAmount consolidates ETH/ERC20 variants.
  • ApprovalFailed(token, spender), NotWhitelistedInCustody(token), PayloadSizeExceeded(provided, maximum) add needed context.

Ensure all emit/revert sites across contracts and tests pass the new parameters correctly, especially PayloadSizeExceeded encodings in deposit/call paths.

Also applies to: 91-94, 102-104, 112-115

test/GatewayEVM.t.sol (3)

537-540: NotWhitelistedInCustody now encoded with token address

Correctly uses abi.encodeWithSelector(NotWhitelistedInCustody.selector, address(token)).

Also applies to: 632-635


547-551: PayloadSizeExceeded assertions now include provided and max sizes

Accurate computation of payloadSize and maxSize; matches new error signature.

Also applies to: 608-612, 708-712, 744-748


576-577: InsufficientEVMAmount selector migration

Consolidation to InsufficientEVMAmount for zero-amount checks looks correct across ETH and ERC20 paths.

Also applies to: 601-602, 677-678, 720-721

contracts/zevm/GatewayZEVM.sol (1)

141-156: Token operations hardened via try/catch — LGTM

Safe wrappers around transferFrom/burn reduce bubble-up reverts and enable precise custom errors.

contracts/zevm/interfaces/IGatewayZEVM.sol (1)

78-91: Error surface improvements look good

Context-rich errors (transfer/burn/deposit failures, message size, invalid gas) are consistent and testable. LGTM.

Also applies to: 92-104, 114-129

contracts/evm/libraries/GatewayEVMValidations.sol (1)

53-59: Call revert options and payload checks — LGTM

Forbidding callOnRevert and enforcing combined payload size matches intended public API guarantees.

Also applies to: 102-113

test/utils/upgrades/GatewayZEVMUpgradeTest.sol (3)

200-211: Confirm event choices and chainId.

First withdraw emits WithdrawnV2 with chainId = 0; custom-gas withdraw emits Withdrawn. Is this divergence intentional for the upgrade test surface and do tests assert it? If not, standardize.

Also applies to: 236-247


402-407: Good: deposit safety wrappers and contextual errors.

_validateDepositParams plus _safeDeposit with ZRC20DepositFailed(zrc20, target, amount) improves safety and debuggability.

Also applies to: 449-453, 489-493


30-32: INotSupportedMethods is already imported via Errors.sol
The interface is declared in contracts/Errors.sol and that file is imported at the top of GatewayZEVMUpgradeTest.sol; no missing import exists.

Likely an incorrect or invalid review comment.

/// @dev Validates that amount is not zero.
/// @param amount The amount to validate.
function validateAmount(uint256 amount) internal pure {
if (amount == 0) revert IGatewayEVMErrors.InsufficientEVMAmount();
Copy link
Member

Choose a reason for hiding this comment

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

Would say ZeroAmount rather than Insufficient

/// @dev Validates that amount is not zero
/// @param amount The amount to validate
function validateAmount(uint256 amount) internal pure {
if (amount == 0) revert IGatewayZEVMErrors.InsufficientAmount();
Copy link
Member

Choose a reason for hiding this comment

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

Same

GatewayZEVMValidations.validateWithdrawalParams(receiver, amount, revertOptions);

uint256 gasFee = _withdrawZRC20(amount, zrc20);
uint256 gasFee = _withdrawZRC20WithGasLimit(amount, zrc20, IZRC20(zrc20).GAS_LIMIT());
Copy link
Member

Choose a reason for hiding this comment

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

Context on this change? Seems out of scope of the PR?

function _resetApproval(address token, address to) private returns (bool) {
return IERC20(token).approve(to, 0);
// Use low-level call to handle tokens that don't return boolean values
(bool success, bytes memory returnData) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, 0));
Copy link
Member

Choose a reason for hiding this comment

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

Same, looks out of scope?

vm.prank(protocolAddress);
gateway.depositAndCall(context, amount, address(gateway), message);
}
// function testDepositZETAAndCallUniversalContractFailsIfTargetIsZeroAddress() public {
Copy link
Member

Choose a reason for hiding this comment

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

Let's not keep uncommented code without context, we should provide comment why it's commented with eventual tracked issue or remove if no longer necessary

@s2imonovic s2imonovic closed this Oct 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants