-
Notifications
You must be signed in to change notification settings - Fork 59
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: prevent using 0 gas limit for call and withdrawAndCall #370
Conversation
📝 WalkthroughWalkthroughThe changes introduced in the Changes
Possibly related PRs
Suggested reviewers
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
Documentation and Community
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #370 +/- ##
==========================================
+ Coverage 83.07% 83.29% +0.21%
==========================================
Files 8 8
Lines 384 389 +5
Branches 122 127 +5
==========================================
+ Hits 319 324 +5
Misses 65 65 ☔ View full report in Codecov by Sentry. |
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.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (1)
v2/contracts/zevm/interfaces/IGatewayZEVM.sol (1)
89-91
: LGTM! Consider adding a comment for clarity.The addition of the
InsufficientGasLimit
error aligns well with the PR objective to prevent passing 0 gas limit. This error will allow for more specific handling of gas limit issues in the contract implementation.Consider adding a brief comment to explain when this error is thrown, for example:
/// @notice Error indicating an insufficient gas limit. /// @dev Thrown when the provided gas limit is too low or zero. error InsufficientGasLimit();
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (48)
v2/docs/src/contracts/Revert.sol/interface.Revertable.md
is excluded by!v2/docs/**
v2/docs/src/contracts/Revert.sol/struct.RevertContext.md
is excluded by!v2/docs/**
v2/docs/src/contracts/Revert.sol/struct.RevertOptions.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/ERC20Custody.sol/contract.ERC20Custody.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/GatewayEVM.sol/contract.GatewayEVM.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/ZetaConnectorBase.sol/abstract.ZetaConnectorBase.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/ZetaConnectorNative.sol/contract.ZetaConnectorNative.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/ZetaConnectorNonNative.sol/contract.ZetaConnectorNonNative.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IERC20Custody.sol/interface.IERC20Custody.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IERC20Custody.sol/interface.IERC20CustodyErrors.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IERC20Custody.sol/interface.IERC20CustodyEvents.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IGatewayEVM.sol/interface.Callable.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IGatewayEVM.sol/interface.IGatewayEVM.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IGatewayEVM.sol/interface.IGatewayEVMErrors.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IGatewayEVM.sol/interface.IGatewayEVMEvents.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IGatewayEVM.sol/struct.MessageContext.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IZetaConnector.sol/interface.IZetaConnectorEvents.md
is excluded by!v2/docs/**
v2/docs/src/contracts/evm/interfaces/IZetaNonEthNew.sol/interface.IZetaNonEthNew.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/GatewayZEVM.sol/contract.GatewayZEVM.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/SystemContract.sol/contract.SystemContract.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/SystemContract.sol/interface.SystemContractErrors.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/ZRC20.sol/contract.ZRC20.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/ZRC20.sol/interface.ZRC20Errors.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IGatewayZEVM.sol/interface.IGatewayZEVM.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IGatewayZEVM.sol/interface.IGatewayZEVMErrors.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IGatewayZEVM.sol/interface.IGatewayZEVMEvents.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IGatewayZEVM.sol/struct.CallOptions.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/ISystem.sol/interface.ISystem.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IWZETA.sol/interface.IWETH9.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IZRC20.sol/enum.CoinType.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IZRC20.sol/interface.IZRC20.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IZRC20.sol/interface.IZRC20Metadata.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/IZRC20.sol/interface.ZRC20Events.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/UniversalContract.sol/interface.UniversalContract.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/UniversalContract.sol/interface.zContract.md
is excluded by!v2/docs/**
v2/docs/src/contracts/zevm/interfaces/UniversalContract.sol/struct.zContext.md
is excluded by!v2/docs/**
v2/pkg/gatewayevmzevm.t.sol/gatewayevmzevmtest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayzevm.sol/gatewayzevm.go
is excluded by!v2/pkg/**
v2/pkg/gatewayzevm.t.sol/gatewayzevminboundtest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayzevm.t.sol/gatewayzevmoutboundtest.go
is excluded by!v2/pkg/**
v2/pkg/igatewayzevm.sol/igatewayzevm.go
is excluded by!v2/pkg/**
v2/pkg/igatewayzevm.sol/igatewayzevmerrors.go
is excluded by!v2/pkg/**
v2/pkg/senderzevm.sol/senderzevm.go
is excluded by!v2/pkg/**
v2/pkg/zrc20.t.sol/zrc20test.go
is excluded by!v2/pkg/**
v2/types/factories/GatewayZEVM__factory.ts
is excluded by!v2/types/**
v2/types/factories/IGatewayZEVM.sol/IGatewayZEVMErrors__factory.ts
is excluded by!v2/types/**
v2/types/factories/IGatewayZEVM.sol/IGatewayZEVM__factory.ts
is excluded by!v2/types/**
v2/types/factories/SenderZEVM__factory.ts
is excluded by!v2/types/**
📒 Files selected for processing (3)
- v2/contracts/zevm/GatewayZEVM.sol (5 hunks)
- v2/contracts/zevm/interfaces/IGatewayZEVM.sol (1 hunks)
- v2/test/GatewayZEVM.t.sol (4 hunks)
🔇 Additional comments (6)
v2/contracts/zevm/interfaces/IGatewayZEVM.sol (2)
Line range hint
1-324
: Summary: New error added to enhance gas limit handlingThe addition of the
InsufficientGasLimit
error to theIGatewayZEVMErrors
interface is a focused change that enhances the contract's ability to handle gas limit issues. This change:
- Aligns with the PR objective to prevent passing 0 gas limit.
- Maintains consistency with the existing error structure in the interface.
- Provides a specific error for gas limit-related issues, improving error handling and debugging.
The impact of this change is minimal on the interface level but potentially significant for the contract implementation. Ensure that the new error is utilized appropriately in the contract code, particularly in functions dealing with gas limits.
89-91
: Verify usage of InsufficientGasLimit error in contract implementationThe new
InsufficientGasLimit
error has been added to the interface, which is good. To ensure it's being used correctly:
- Verify that this error is thrown in the contract implementation when a zero or insufficient gas limit is provided.
- Check functions like
withdrawAndCall
andcall
that acceptgasLimit
orCallOptions
to ensure they use this error appropriately.To help verify the implementation, you can run the following script:
This script will help identify where the new error is being used and where gas limit checks are performed in the codebase.
✅ Verification successful
InsufficientGasLimit error is correctly implemented and utilized
The
InsufficientGasLimit
error is properly used in the contract implementation. Multiple functions, includingwithdrawAndCall
andcall
, revert withInsufficientGasLimit
when thegasLimit
is zero. Additionally, corresponding tests ensure that this error handling is validated.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for the usage of InsufficientGasLimit error in the contract implementation echo "Searching for InsufficientGasLimit usage:" rg --type solidity "InsufficientGasLimit" -C 5 echo "\nSearching for gas limit checks:" rg --type solidity "gasLimit\s*==?\s*0" -C 5 rg --type solidity "gasLimit\s*[<>]=?\s*" -C 5Length of output: 411
Script:
#!/bin/bash # Search for the usage of InsufficientGasLimit error in Solidity files echo "Searching for InsufficientGasLimit usage in .sol files:" rg "InsufficientGasLimit" --glob "*.sol" -C 5 echo "\nSearching for gas limit checks in .sol files:" rg "gasLimit\s*==?\s*0" --glob "*.sol" -C 5 rg "gasLimit\s*[<>]=?\s*" --glob "*.sol" -C 5Length of output: 14831
v2/test/GatewayZEVM.t.sol (4)
155-159
: Test correctly handles zero gas limit forwithdrawAndCallZRC20
The test function
testWithdrawAndCallZRC20FailsIfGasLimitIsZero
properly verifies that callingwithdrawAndCall
with a gas limit of zero reverts withInsufficientGasLimit.selector
.
216-221
: Test correctly handles zero gas limit incallOptions
forwithdrawAndCallZRC20
The test function
testWithdrawAndCallZRC20WithCallOptsFailsIfGasLimitIsZero
correctly setscallOptions.gasLimit
to zero and expects a revert withInsufficientGasLimit.selector
when callingwithdrawAndCall
.
511-515
: Test correctly handles zero gas limit forcall
The test function
testCallFailsIfGasLimitIsZero
accurately expects a revert withInsufficientGasLimit.selector
whengateway.call
is invoked with a gas limit of zero.
531-536
: Test correctly handles zero gas limit incallOptions
forcall
The test function
testCallWithCallOptsFailsIfGasLimitIsZero
properly setscallOptions.gasLimit
to zero and verifies thatgateway.call
reverts withInsufficientGasLimit.selector
.
@@ -177,6 +177,7 @@ contract GatewayZEVM is | |||
{ | |||
if (receiver.length == 0) revert ZeroAddress(); | |||
if (amount == 0) revert InsufficientZRC20Amount(); | |||
if (gasLimit == 0) revert InsufficientGasLimit(); |
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.
Define InsufficientGasLimit
error
The error InsufficientGasLimit()
is used but not defined in the contract. Please define the InsufficientGasLimit
error to maintain consistency with other error handling.
Suggested addition:
/// @notice Error indicating that the provided gas limit is zero.
error InsufficientGasLimit();
Place this definition alongside other error definitions in the contract.
Also applies to: 218-218, 323-323, 348-348, 370-370
Add unit tests for gas limit validations
To ensure the new InsufficientGasLimit
checks function as intended, please add unit tests that verify the contract correctly reverts when a zero gas limit is provided.
Also applies to: 218-218, 323-323, 348-348, 370-370
function testWithdrawZETAWithCallOptsWithMessageFailsIfGasLimitIsZero() public { | ||
uint256 amount = 1; | ||
uint256 ownerBalanceBefore = zetaToken.balanceOf(owner); | ||
uint256 gatewayBalanceBefore = zetaToken.balanceOf(address(gateway)); | ||
uint256 protocolAddressBalanceBefore = protocolAddress.balance; | ||
bytes memory message = abi.encodeWithSignature("hello(address)", addr1); | ||
uint256 chainId = 1; | ||
|
||
// Remove allowance for gateway | ||
vm.prank(owner); | ||
zetaToken.approve(address(gateway), 0); | ||
|
||
callOptions.gasLimit = 0; | ||
vm.expectRevert(InsufficientGasLimit.selector); | ||
gateway.withdrawAndCall(abi.encodePacked(addr1), amount, chainId, message, callOptions, revertOptions); | ||
} |
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.
Test may not correctly validate gas limit zero due to zero allowance
In the test function testWithdrawZETAWithCallOptsWithMessageFailsIfGasLimitIsZero
, the allowance for the gateway is removed by setting zetaToken.approve(address(gateway), 0);
before setting callOptions.gasLimit = 0
. This causes the withdrawAndCall
call to revert due to insufficient allowance, potentially causing the test to fail for the wrong reason.
Apply this diff to fix the test:
- // Remove allowance for gateway
- vm.prank(owner);
- zetaToken.approve(address(gateway), 0);
callOptions.gasLimit = 0;
vm.expectRevert(InsufficientGasLimit.selector);
gateway.withdrawAndCall(abi.encodePacked(addr1), amount, chainId, message, callOptions, revertOptions);
By removing the code that resets the allowance, the test will correctly check for a revert due to an InsufficientGasLimit
, ensuring the test validates the intended behavior.
📝 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.
function testWithdrawZETAWithCallOptsWithMessageFailsIfGasLimitIsZero() public { | |
uint256 amount = 1; | |
uint256 ownerBalanceBefore = zetaToken.balanceOf(owner); | |
uint256 gatewayBalanceBefore = zetaToken.balanceOf(address(gateway)); | |
uint256 protocolAddressBalanceBefore = protocolAddress.balance; | |
bytes memory message = abi.encodeWithSignature("hello(address)", addr1); | |
uint256 chainId = 1; | |
// Remove allowance for gateway | |
vm.prank(owner); | |
zetaToken.approve(address(gateway), 0); | |
callOptions.gasLimit = 0; | |
vm.expectRevert(InsufficientGasLimit.selector); | |
gateway.withdrawAndCall(abi.encodePacked(addr1), amount, chainId, message, callOptions, revertOptions); | |
} | |
function testWithdrawZETAWithCallOptsWithMessageFailsIfGasLimitIsZero() public { | |
uint256 amount = 1; | |
uint256 ownerBalanceBefore = zetaToken.balanceOf(owner); | |
uint256 gatewayBalanceBefore = zetaToken.balanceOf(address(gateway)); | |
uint256 protocolAddressBalanceBefore = protocolAddress.balance; | |
bytes memory message = abi.encodeWithSignature("hello(address)", addr1); | |
uint256 chainId = 1; | |
callOptions.gasLimit = 0; | |
vm.expectRevert(InsufficientGasLimit.selector); | |
gateway.withdrawAndCall(abi.encodePacked(addr1), amount, chainId, message, callOptions, revertOptions); | |
} |
Summary by CodeRabbit
New Features
withdrawAndCall
andcall
functions.withdrawAndCall
andcall
functions to accept flexible gas limit specifications.Bug Fixes
Tests