-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: erc20 auth calls #401
Conversation
📝 Walkthrough📝 WalkthroughWalkthroughThe pull request introduces significant updates across multiple contracts and their corresponding tests, primarily focusing on the addition of a 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 #401 +/- ##
=======================================
Coverage 84.23% 84.23%
=======================================
Files 8 8
Lines 387 387
Branches 121 122 +1
=======================================
Hits 326 326
Misses 61 61 ☔ 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: 18
🧹 Outside diff range and nitpick comments (15)
v2/test/utils/IReceiverEVM.sol (1)
40-43
: LGTM! Consider enhancing themessage
parameter description.The updated
ReceivedOnCall
event now includessender
andmessage
parameters, which significantly improves the context provided when the event is emitted. This change aligns well with the PR objectives of enhancing authentication for calls.Consider slightly expanding the description for the
message
parameter to provide more context about its contents. For example:/// @notice Emitted when onCall function is called with authenticated call. /// @param sender Message context sender. -/// @param message Message received. +/// @param message Encoded message data received in the authenticated call. event ReceivedOnCall(address sender, bytes message);This minor change would provide more clarity about the nature of the
message
parameter.v2/test/utils/ReceiverEVM.sol (1)
Line range hint
76-85
: Approve event emission change and suggest improvementsThe updated event emission in the
onCall
function is a good improvement, providing more context by including the sender and message data. This change is approved.However, there are a couple of points to consider for further improvement:
The function is marked as
payable
, butmsg.value
is not used anywhere in the function. If there's no intention to use the sent Ether, consider removing thepayable
modifier to prevent accidental Ether transfers.The function declares a return type
bytes memory
, but it doesn't actually return anything. Either add a return statement if a return value is intended, or remove the return type from the function signature if no return value is needed.Consider applying these changes:
function onCall( MessageContext calldata messageContext, bytes calldata message ) external - payable - returns (bytes memory) { emit ReceivedOnCall(messageContext.sender, message); + return ""; // Or remove if no return value is needed }v2/contracts/evm/interfaces/IERC20Custody.sol (1)
Line range hint
5-88
: Overall impact: Focused enhancement with potential ripple effectsThe changes to the
IERC20Custody
interface are focused and consistent with the described modifications. The addition of theMessageContext
parameter towithdrawAndCall
suggests an improvement in contextual information for operations. While the impact is limited to this specific function, all implementations and calls towithdrawAndCall
will need to be updated, which could have a ripple effect through the codebase.To ensure the changes are properly integrated:
- Update all implementations of
IERC20Custody
to include the newMessageContext
parameter inwithdrawAndCall
.- Modify all calls to
withdrawAndCall
throughout the codebase to provide the requiredMessageContext
.- Conduct thorough testing, including integration tests, to verify that the changes don't introduce any regressions or unexpected behavior.
- Update relevant documentation to reflect the new function signature and its usage.
v2/contracts/evm/ZetaConnectorNonNative.sol (2)
Line range hint
64-89
: LGTM! Consider updating the function documentation.The changes to the
withdrawAndCall
function look good. The addition of theMessageContext
parameter enhances the context for the withdrawal operation, which is then correctly passed to thegateway.executeWithERC20
function.Consider updating the function documentation to include a description of the new
messageContext
parameter:/// @notice Withdraw tokens and call a contract through Gateway. +/// @param messageContext Message context containing sender information. /// @param to The address to withdraw tokens to. /// @param amount The amount of tokens to withdraw. /// @param data The calldata to pass to the contract call. /// @param internalSendHash A hash used for internal tracking of the transaction. /// @dev This function can only be called by the TSS address, and mints if supply is not reached.
Line range hint
1-143
: Consider similar updates to other withdrawal functions for consistency.The
withdrawAndCall
function has been updated to include aMessageContext
parameter, which enhances the context for the withdrawal operation. For consistency and potential future-proofing, you might want to consider similar updates to thewithdraw
andwithdrawAndRevert
functions.If these functions don't require the additional context, it's fine to leave them as is. However, if there's a possibility they might benefit from this context in the future, consider updating them preemptively:
function withdraw( MessageContext calldata messageContext, address to, uint256 amount, bytes32 internalSendHash ) external override nonReentrant onlyRole(WITHDRAWER_ROLE) whenNotPaused { // ... (existing implementation) } function withdrawAndRevert( MessageContext calldata messageContext, address to, uint256 amount, bytes calldata data, bytes32 internalSendHash, RevertContext calldata revertContext ) external override nonReentrant onlyRole(WITHDRAWER_ROLE) whenNotPaused { // ... (existing implementation) }This suggestion is optional and depends on your specific use case and future plans for these functions.
v2/contracts/evm/ZetaConnectorBase.sol (1)
Line range hint
1-159
: Overall assessment: Changes look good, but verify integration.The modifications to the
ZetaConnectorBase
contract, including the updated import statement and thewithdrawAndCall
function signature, are consistent and well-implemented. These changes appear to be part of a larger update to include message context in various operations across the system.However, it's crucial to ensure that these changes are properly integrated throughout the codebase. Please verify that:
- All derived contracts have been updated to match the new
withdrawAndCall
function signature.- All calling code has been modified to provide the required
MessageContext
parameter.- The
MessageContext
type is correctly defined in theIGatewayEVM
interface.- The changes don't introduce any breaking changes in the contract's behavior or interactions with other parts of the system.
Consider updating the contract's documentation to reflect the new
MessageContext
parameter and its significance in thewithdrawAndCall
operation. This will help maintain clear and up-to-date documentation for developers working with this contract.v2/test/GatewayEVMZEVM.t.sol (2)
53-53
: Consider using a more meaningful default address forarbitraryCallMessageContext
.The newly added
arbitraryCallMessageContext
variable usesaddress(0)
as the default sender. While this might work for testing purposes, it's generally not recommended to use the zero address as it can lead to unexpected behavior or make debugging more difficult.Consider using a dedicated test address or one of the existing addresses in the test setup (e.g.,
ownerEVM
ortssAddress
) as the default sender. Additionally, it would be helpful to add a comment explaining the purpose of this variable and why it's being introduced.
Line range hint
53-278
: Consider refining the use ofarbitraryCallMessageContext
across test cases.The introduction of
arbitraryCallMessageContext
and its use in theexecute
function calls is consistent across all modified test functions. This change aligns with the updated function signature and is necessary for the tests to pass.However, to enhance the robustness and accuracy of these tests, consider the following improvements:
Instead of using a single
arbitraryCallMessageContext
withaddress(0)
as the sender, create different contexts for each test case that accurately represent the scenario being tested (e.g., direct calls, calls from ZEVM, withdrawals, etc.).Add comments explaining the purpose and expected behavior of
arbitraryCallMessageContext
in each test case.Consider adding additional test cases that specifically verify the behavior of the
execute
function with different message contexts.These refinements would make the tests more comprehensive and better aligned with the actual use cases of the contract.
v2/contracts/evm/interfaces/IGatewayEVM.sol (1)
Line range hint
191-193
: Include 'arbitrary call flag' inMessageContext
Struct or Update DocumentationThe
MessageContext
struct currently only includes thesender
field, but the documentation suggests it should also contain an "arbitrary call flag." If this flag is necessary for your implementation, consider adding it to the struct. Otherwise, update the documentation to match the struct's actual fields.To include the "arbitrary call flag," apply this diff:
struct MessageContext { address sender; + bool arbitraryCallFlag; }
v2/test/utils/upgrades/ERC20CustodyUpgradeTest.sol (1)
Validation Missing for
MessageContext
inwithdrawAndCall
The
withdrawAndCall
function invokesgateway.executeWithERC20
withmessageContext
without performing any validation checks. Norequire
orassert
statements were found to validatemessageContext
, which could expose the contract to malicious inputs or reentrancy attacks.
- File:
v2/test/utils/upgrades/ERC20CustodyUpgradeTest.sol
- Lines: 144-156
🔗 Analysis chain
Line range hint
147-170
: ValidateMessageContext
inwithdrawAndCall
The
withdrawAndCall
function now acceptsMessageContext calldata messageContext
:function withdrawAndCall( MessageContext calldata messageContext, address to, address token, uint256 amount, bytes calldata data ) public nonReentrant onlyRole(WITHDRAWER_ROLE) whenNotPaused { // ... gateway.executeWithERC20(messageContext, token, to, amount, data); // ... }Ensure that
messageContext
is properly validated before being used. Lack of validation could expose the contract to malicious inputs or reentrancy attacks.Consider adding validation checks for
messageContext
to ensure it contains expected and safe values.Run the following script to check for validation of
messageContext
:🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Search for validation logic involving MessageContext in the contract. # Test: Look for `require` or `assert` statements validating `messageContext` rg --type solidity 'require.*messageContext' -A 5Length of output: 156
Script:
#!/bin/bash # Description: Search for validation logic involving MessageContext in Solidity contracts. # Test: Look for `require` or `assert` statements validating `messageContext` in `.sol` files rg 'require.*messageContext|assert.*messageContext' --type-add 'solidity:*.sol' --type solidity -A 5Length of output: 102
Script:
#!/bin/bash # Description: Explore usage and validation of MessageContext in Solidity contracts. # Search for the definition of MessageContext rg 'struct\s+MessageContext' --type-add 'solidity:*.sol' --type solidity # Search for any functions or modifiers that include 'validate' and 'messageContext' rg 'function\s+\w*\s*\(.*messageContext.*\)' --type-add 'solidity:*.sol' --type solidity -A 5 rg 'modifier\s+\w*\s*\(.*messageContext.*\)' --type-add 'solidity:*.sol' --type solidity -A 5 # Search for any inheritance that might include validation logic rg 'is\s+\w+' --type-add 'solidity:*.sol' --type solidity # Search for imported contracts that might validate MessageContext rg 'import\s+"[^"]*"' --type-add 'solidity:*.sol' --type solidity -A 2Length of output: 67969
v2/contracts/evm/GatewayEVM.sol (1)
182-186
: Add comments to clarify the conditional logic based onmessageContext.sender
Similar to the
execute
function, theexecuteWithERC20
function uses the conditionmessageContext.sender == address(0)
to differentiate between arbitrary and authenticated calls. Adding explanatory comments can enhance code readability and maintainability.Apply this diff to add explanatory comments:
if (messageContext.sender == address(0)) { + // If sender is the zero address, perform an arbitrary call _executeArbitraryCall(to, data); } else { + // Otherwise, perform an authenticated call with messageContext _executeAuthenticatedCall(messageContext, to, data); }v2/test/utils/upgrades/GatewayEVMUpgradeTest.sol (2)
246-246
: Consider makingMAX_PAYLOAD_SIZE
configurableThe checks for
payload.length + revertOptions.revertMessage.length
againstMAX_PAYLOAD_SIZE
use a hardcoded limit of1024
. While this adds a safeguard, consider makingMAX_PAYLOAD_SIZE
a configurable parameter to allow flexibility for different use cases.You can implement this by adding a setter function with appropriate access control:
- uint256 public constant MAX_PAYLOAD_SIZE = 1024; + uint256 public MAX_PAYLOAD_SIZE; + /// @notice Sets the maximum payload size. + /// @param maxSize The new maximum size. + function setMaxPayloadSize(uint256 maxSize) external onlyRole(DEFAULT_ADMIN_ROLE) { + MAX_PAYLOAD_SIZE = maxSize; + }This allows administrators to adjust the limit as needed.
Also applies to: 272-272, 295-295, 323-323, 344-344
25-25
: Update event names consistently after version changeThe event
Executed
has been renamed toExecutedV2
to indicate a version change. Ensure that all related events and their usages are consistently updated to reflect the new versioning scheme. Additionally, consider versioning other events or providing deprecation notices for old events to maintain consistency.You might also want to update other related events for consistency:
- event Reverted(address indexed destination, address token, uint256 value, bytes data, RevertContext revertContext); + event RevertedV2(address indexed destination, address token, uint256 value, bytes data, RevertContext revertContext);This helps in maintaining a clear event history with versioning.
v2/test/ZetaConnectorNonNative.t.sol (1)
44-44
: Consider initializingarbitraryCallMessageContext
within each test functionCurrently,
arbitraryCallMessageContext
is initialized at the contract level withsender: address(0)
. To enhance test clarity and isolation, consider initializingMessageContext
within each test function with context-specificsender
addresses. This approach ensures that each test accurately reflects its scenario without relying on a shared state.v2/test/ZetaConnectorNative.t.sol (1)
44-44
: Consider declaringarbitraryCallMessageContext
as a constant.Since
arbitraryCallMessageContext
is initialized once and not modified throughout the tests, declaring it as aconstant
can improve code clarity and indicate that it should not be changed.Apply this change:
- MessageContext arbitraryCallMessageContext = MessageContext({ sender: address(0) }); + MessageContext constant arbitraryCallMessageContext = MessageContext({ sender: address(0) });
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (52)
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/IGatewayEVM.sol/interface.IGatewayEVM.md
is excluded by!v2/docs/**
v2/pkg/erc20custody.sol/erc20custody.go
is excluded by!v2/pkg/**
v2/pkg/erc20custody.t.sol/erc20custodytest.go
is excluded by!v2/pkg/**
v2/pkg/erc20custodyupgradetest.sol/erc20custodyupgradetest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevm.sol/gatewayevm.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevm.t.sol/gatewayevminboundtest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevm.t.sol/gatewayevmtest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevmupgradetest.sol/gatewayevmupgradetest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevmzevm.t.sol/gatewayevmzevmtest.go
is excluded by!v2/pkg/**
v2/pkg/ierc20custody.sol/ierc20custody.go
is excluded by!v2/pkg/**
v2/pkg/igatewayevm.sol/igatewayevm.go
is excluded by!v2/pkg/**
v2/pkg/ireceiverevm.sol/ireceiverevmevents.go
is excluded by!v2/pkg/**
v2/pkg/receiverevm.sol/receiverevm.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectorbase.sol/zetaconnectorbase.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornative.sol/zetaconnectornative.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornative.t.sol/zetaconnectornativetest.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornativeupgradetest.sol/zetaconnectornativeupgradetest.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornonnative.sol/zetaconnectornonnative.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornonnative.t.sol/zetaconnectornonnativetest.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornonnativeupgradetest.sol/zetaconnectornonnativeupgradetest.go
is excluded by!v2/pkg/**
v2/types/ERC20Custody.ts
is excluded by!v2/types/**
v2/types/ERC20CustodyUpgradeTest.ts
is excluded by!v2/types/**
v2/types/GatewayEVM.ts
is excluded by!v2/types/**
v2/types/GatewayEVMUpgradeTest.ts
is excluded by!v2/types/**
v2/types/IERC20Custody.sol/IERC20Custody.ts
is excluded by!v2/types/**
v2/types/IGatewayEVM.sol/IGatewayEVM.ts
is excluded by!v2/types/**
v2/types/IReceiverEVM.sol/IReceiverEVMEvents.ts
is excluded by!v2/types/**
v2/types/ReceiverEVM.ts
is excluded by!v2/types/**
v2/types/ZetaConnectorBase.ts
is excluded by!v2/types/**
v2/types/ZetaConnectorNative.ts
is excluded by!v2/types/**
v2/types/ZetaConnectorNativeUpgradeTest.ts
is excluded by!v2/types/**
v2/types/ZetaConnectorNonNative.ts
is excluded by!v2/types/**
v2/types/ZetaConnectorNonNativeUpgradeTest.ts
is excluded by!v2/types/**
v2/types/factories/ERC20CustodyUpgradeTest__factory.ts
is excluded by!v2/types/**
v2/types/factories/ERC20Custody__factory.ts
is excluded by!v2/types/**
v2/types/factories/GatewayEVMUpgradeTest__factory.ts
is excluded by!v2/types/**
v2/types/factories/GatewayEVM__factory.ts
is excluded by!v2/types/**
v2/types/factories/IERC20Custody.sol/IERC20Custody__factory.ts
is excluded by!v2/types/**
v2/types/factories/IGatewayEVM.sol/IGatewayEVM__factory.ts
is excluded by!v2/types/**
v2/types/factories/IReceiverEVM.sol/IReceiverEVMEvents__factory.ts
is excluded by!v2/types/**
v2/types/factories/ReceiverEVM__factory.ts
is excluded by!v2/types/**
v2/types/factories/ZetaConnectorBase__factory.ts
is excluded by!v2/types/**
v2/types/factories/ZetaConnectorNativeUpgradeTest__factory.ts
is excluded by!v2/types/**
v2/types/factories/ZetaConnectorNative__factory.ts
is excluded by!v2/types/**
v2/types/factories/ZetaConnectorNonNativeUpgradeTest__factory.ts
is excluded by!v2/types/**
v2/types/factories/ZetaConnectorNonNative__factory.ts
is excluded by!v2/types/**
📒 Files selected for processing (18)
- v2/contracts/evm/ERC20Custody.sol (3 hunks)
- v2/contracts/evm/GatewayEVM.sol (3 hunks)
- v2/contracts/evm/ZetaConnectorBase.sol (2 hunks)
- v2/contracts/evm/ZetaConnectorNative.sol (2 hunks)
- v2/contracts/evm/ZetaConnectorNonNative.sol (2 hunks)
- v2/contracts/evm/interfaces/IERC20Custody.sol (2 hunks)
- v2/contracts/evm/interfaces/IGatewayEVM.sol (1 hunks)
- v2/test/ERC20Custody.t.sol (12 hunks)
- v2/test/GatewayEVM.t.sol (9 hunks)
- v2/test/GatewayEVMZEVM.t.sol (5 hunks)
- v2/test/ZetaConnectorNative.t.sol (6 hunks)
- v2/test/ZetaConnectorNonNative.t.sol (7 hunks)
- v2/test/utils/IReceiverEVM.sol (1 hunks)
- v2/test/utils/ReceiverEVM.sol (1 hunks)
- v2/test/utils/upgrades/ERC20CustodyUpgradeTest.sol (5 hunks)
- v2/test/utils/upgrades/GatewayEVMUpgradeTest.sol (19 hunks)
- v2/test/utils/upgrades/ZetaConnectorNativeUpgradeTest.sol (2 hunks)
- v2/test/utils/upgrades/ZetaConnectorNonNativeUpgradeTest.sol (3 hunks)
🧰 Additional context used
🔇 Additional comments (49)
v2/contracts/evm/ZetaConnectorNative.sol (1)
Line range hint
48-71
: LGTM! Consider verifying impacts on calling code.The changes to the
withdrawAndCall
function look good. The addition of theMessageContext
parameter enhances the context information passed to the function, and the updates to both the function comment and thegateway.executeWithERC20
call are consistent with this change.To ensure these changes don't introduce any issues, please verify:
- All calls to
withdrawAndCall
in other contracts have been updated to include the newMessageContext
parameter.- Any tests involving
withdrawAndCall
have been updated to reflect the new function signature.You can use the following script to check for potential places that might need updates:
This script will help identify areas of the codebase that might need attention due to the signature change.
v2/test/utils/upgrades/ZetaConnectorNativeUpgradeTest.sol (3)
Line range hint
20-20
: LGTM: New eventWithdrawnV2
added for upgrade testing.The new event
WithdrawnV2
is correctly implemented with relevant parameters for tracking withdrawals. The "V2" suffix in the name clearly indicates it's an upgraded version of a previous event.
Line range hint
1-118
: Summary: Changes inZetaConnectorNativeUpgradeTest.sol
look good overall.The modifications to this contract, including the new
WithdrawnV2
event and the updatedwithdrawAndCall
function, are well-implemented and align with the PR objectives. The changes enhance the context for withdrawal operations by introducing theMessageContext
parameter.To ensure the consistency of these changes across the codebase:
- Verify that all calls to
withdrawAndCall
in other contracts are updated to include the newMessageContext
parameter.- Confirm that the
Gateway
contract'sexecuteWithERC20
function has been updated to accept theMessageContext
parameter.These verifications will help maintain the integrity of the system after the upgrade.
75-75
: LGTM: Updated gateway call with newmessageContext
parameter.The
gateway.executeWithERC20
call has been correctly updated to include the newmessageContext
parameter.To ensure consistency, please verify that the
Gateway
contract'sexecuteWithERC20
function has been updated to accept theMessageContext
parameter:#!/bin/bash # Description: Check Gateway contract for updated executeWithERC20 function # Search for the executeWithERC20 function definition in the Gateway contract rg --type solidity 'function\s+executeWithERC20.*?MessageContext' -C 3v2/contracts/evm/interfaces/IERC20Custody.sol (2)
6-6
: LGTM: New import for MessageContextThe addition of this import statement is necessary to support the new
MessageContext
parameter in thewithdrawAndCall
function. This change is consistent with the modifications described in the summary.
81-88
: LGTM: Updated withdrawAndCall signature with MessageContextThe addition of the
MessageContext
parameter to thewithdrawAndCall
function is consistent with the described changes and likely provides valuable context for the operation. This modification enhances the function's capabilities but will require updates in all implementations and calls to this function.To ensure all implementations and calls have been updated accordingly, please run the following script:
v2/contracts/evm/ZetaConnectorBase.sol (2)
Line range hint
120-132
: LGTM! Verify derived contracts and calling code.The
withdrawAndCall
function signature has been correctly updated to include theMessageContext
parameter. The use ofcalldata
for this parameter is appropriate and gas-efficient.To ensure that all derived contracts and calling code have been updated accordingly, please run the following script:
#!/bin/bash # Description: Verify updates in derived contracts and calling code # Test 1: Check for any remaining occurrences of the old function signature rg --type solidity 'function\s+withdrawAndCall\s*\(\s*address\s+to\s*,\s*uint256\s+amount\s*,\s*bytes\s+calldata\s+data\s*,\s*bytes32\s+internalSendHash\s*\)' # Test 2: Check for occurrences of the new function signature in derived contracts rg --type solidity 'function\s+withdrawAndCall\s*\(\s*MessageContext\s+calldata\s+messageContext\s*,\s*address\s+to\s*,\s*uint256\s+amount\s*,\s*bytes\s+calldata\s+data\s*,\s*bytes32\s+internalSendHash\s*\)' # Test 3: Check for function calls to withdrawAndCall rg --type solidity 'withdrawAndCall\s*\('Please review the results to ensure all necessary updates have been made.
13-18
: LGTM! Verify the IGatewayEVM interface.The import statement has been correctly updated to include
MessageContext
. This change is consistent with its usage in thewithdrawAndCall
function.To ensure the
MessageContext
type is correctly defined, please run the following script:v2/test/GatewayEVMZEVM.t.sol (4)
170-170
: Verify if the newarbitraryCallMessageContext
correctly tests the intended behavior.The modification to include
arbitraryCallMessageContext
in theexecute
function call aligns with the updated function signature. This change is correct and necessary.However, since
arbitraryCallMessageContext
is initialized with a default sender ofaddress(0)
, ensure that this adequately tests the intended behavior of theexecute
function. Consider adding test cases with different sender addresses to comprehensively test the function's behavior with various message contexts.
200-200
: Verify if thearbitraryCallMessageContext
correctly represents the sender behavior.The modification to include
arbitraryCallMessageContext
in theexecute
function call is correct and consistent with the updated function signature.However, since this test is specifically for calls from a sender on ZEVM, consider modifying the
arbitraryCallMessageContext
to use a sender address that represents the ZEVM sender (e.g.,address(senderZEVM)
). This would more accurately simulate the expected behavior and provide a more robust test case.
246-246
: EnsurearbitraryCallMessageContext
correctly represents the withdrawal scenario.The modification to include
arbitraryCallMessageContext
in theexecute
function call is correct and consistent with the updated function signature.Given that this test combines withdrawal and execution, it's important to verify if the current
arbitraryCallMessageContext
(with a sender ofaddress(0)
) accurately represents the expected behavior in a withdrawal scenario. Consider modifying the context to use a sender address that reflects the withdrawal initiator (e.g.,ownerZEVM
) to more accurately test this combined functionality.
278-278
: Verify ifarbitraryCallMessageContext
accurately represents the withdrawal from sender ZEVM scenario.The modification to include
arbitraryCallMessageContext
in theexecute
function call is correct and consistent with the updated function signature.This test case combines withdrawal, sender behavior on ZEVM, and execution, which is a complex scenario. It's crucial to ensure that the current
arbitraryCallMessageContext
(with a sender ofaddress(0)
) accurately represents this multi-step process. Consider modifying the context to use a sender address that reflects both the withdrawal initiator and the ZEVM sender (e.g.,address(senderZEVM)
). This would provide a more accurate and comprehensive test of the intended functionality.v2/contracts/evm/ERC20Custody.sol (4)
5-5
: Import updated to includeMessageContext
The inclusion of
MessageContext
in the import statement is appropriate and aligns with the updates to the function signatures.
143-143
: Function documentation updated withmessageContext
parameterThe function comment correctly documents the new
messageContext
parameter, ensuring clarity in the function's usage.
Line range hint
149-153
: FunctionwithdrawAndCall
signature updated appropriatelyThe addition of
MessageContext calldata messageContext
to thewithdrawAndCall
function enhances the contextual information passed during execution.
166-166
: PassingmessageContext
togateway.executeWithERC20
The updated call to
gateway.executeWithERC20
now includesmessageContext
, ensuring that the execution carries the necessary context.v2/test/utils/upgrades/ERC20CustodyUpgradeTest.sol (3)
98-99
: Review the Sequence of UpdatingtssAddress
The
tssAddress
is updated after revoking roles from the old address and before granting roles to the new address:tssAddress = newTSSAddress;
Ensure that updating
tssAddress
at this point is correct and that there are no dependencies ontssAddress
between the role revocation and this assignment.
170-170
: Confirm Parameter Order ingateway.executeWithERC20
CallThe call to
gateway.executeWithERC20
includesmessageContext
as the first argument:gateway.executeWithERC20(messageContext, token, to, amount, data);
Verify that the parameter order matches the function definition in
IGatewayEVM
to prevent any mismatches that could lead to errors.Run the following script to retrieve the function definition and confirm the parameter order:
#!/bin/bash # Description: Retrieve the definition of `executeWithERC20` in `IGatewayEVM` # Test: Confirm parameter order matches usage rg --type solidity 'function executeWithERC20' -A 5
Line range hint
193-208
: ValidateRevertContext
inwithdrawAndRevert
The
withdrawAndRevert
function now includesRevertContext calldata revertContext
:function withdrawAndRevert( address to, address token, uint256 amount, bytes calldata data, RevertContext calldata revertContext ) public nonReentrant onlyRole(WITHDRAWER_ROLE) whenNotPaused { // ... gateway.revertWithERC20(token, to, amount, data, revertContext); // ... }Ensure that
revertContext
is properly validated to prevent misuse. Improper handling might lead to unintended contract behavior.Consider adding necessary validation or sanitization for
revertContext
.Run the following script to check for validation of
revertContext
:#!/bin/bash # Description: Search for validation logic involving RevertContext in the contract. # Test: Look for `require` or `assert` statements validating `revertContext` rg --type solidity 'require.*revertContext' -A 5v2/contracts/evm/GatewayEVM.sol (3)
159-159
: Documentation updated correctly with the new parameterThe function documentation now includes the
messageContext
parameter, accurately reflecting the updated function signature inexecuteWithERC20
. This ensures that the purpose and usage of the parameter are clear to other developers.
182-186
: Verify that all calls toexecuteWithERC20
have been updated with the new signatureThe
executeWithERC20
function now requires aMessageContext
parameter. Ensure that all existing calls to this function are updated accordingly to include this new parameter.Run the following script to identify any calls that may be missing the
MessageContext
parameter:#!/bin/bash # Description: Find all calls to `executeWithERC20` that might not include the new `MessageContext` parameter. # Search for function calls to `executeWithERC20` without `MessageContext` rg --type solidity 'executeWithERC20\(\s*address\b' --files-with-matchesThis script looks for calls to
executeWithERC20
where the first argument is anaddress
, suggesting that theMessageContext
parameter is not included.
145-149
: Verify that all calls toexecute
have been updated with the new signatureThe
execute
function signature now includesMessageContext
. It's important to ensure that all calls to this function throughout the codebase have been updated to match the new signature to prevent compilation errors or unintended behavior.Run the following script to locate any outdated calls to
execute
:This script searches for calls to
execute
where the first argument is anaddress
, indicating that theMessageContext
parameter might be missing.✅ Verification successful
All
execute
function calls are updated with the newMessageContext
parameter.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Find all calls to `execute` that might not include the new `MessageContext` parameter. # Search for function calls to `execute` without `MessageContext` rg --type solidity 'execute\(\s*address\b' --files-with-matchesLength of output: 107
Script:
#!/bin/bash # Description: Find all calls to `execute` that might not include the new `MessageContext` parameter. # Search for function calls to `execute` without `MessageContext` in .sol files rg 'execute\(\s*address\b' --glob '*.sol' --files-with-matchesLength of output: 64
v2/test/utils/upgrades/GatewayEVMUpgradeTest.sol (3)
386-397
: Confirm the handling of ZETA token depositsThe code related to handling ZETA token deposits is commented out, and a
ZETANotSupported
error is reverted instead. Ensure that this is the intended behavior for the current release. Additionally, consider adding tests to cover this scenario and plan for re-enabling the code when support for ZETA deposits is implemented.Would you like assistance in creating unit tests for the
ZETANotSupported
scenario or in planning the reintroduction of ZETA token support?
149-153
: Validate the condition for executing arbitrary or authenticated callsThe condition
if (messageContext.sender == address(0))
is used to determine whether to execute an arbitrary call or an authenticated call. Ensure thatmessageContext.sender
being zero accurately reflects an unauthenticated context.Run the following script to confirm that
messageContext.sender
is set appropriately throughout the codebase:#!/bin/bash # Description: Verify that messageContext.sender is correctly initialized and used. # Test: Search for initializations and usages of MessageContext. # Expected result: Consistent handling of messageContext.sender across functions. # Search for MessageContext initializations rg --type solidity 'MessageContext\s+memory\s+\w+\s*=\s*MessageContext\({' # Search for usages of messageContext.sender rg --type solidity 'messageContext\.sender'This will help ensure that the logic based on
messageContext.sender
is sound and that there are no scenarios where it might unintentionally be zero.Also applies to: 186-190
374-374
: Verify that making functions private does not affect external callsThe functions
_resetApproval
,_transferFromToAssetHandler
, and_transferToAssetHandler
have been changed toprivate
. Ensure that these functions are not called from derived contracts or external sources to prevent breaking functionality.Run the following script to check for any external calls to these functions:
This script searches for any occurrences of these function calls outside their defining context. Ensure that no matches are found outside the
GatewayEVMUpgradeTest
contract.Also applies to: 384-384, 410-410
✅ Verification successful
Verification Successful: Private Functions Are Not Exposed Externally
- No external calls to
_resetApproval
,_transferFromToAssetHandler
, or_transferToAssetHandler
were found outside their defining contracts.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the functions made private are not called externally. # Test: Search for external calls to the private functions. # Expected result: No external calls found. # Search for external calls to _resetApproval rg --type solidity '_resetApproval\(' # Search for external calls to _transferFromToAssetHandler rg --type solidity '_transferFromToAssetHandler\(' # Search for external calls to _transferToAssetHandler rg --type solidity '_transferToAssetHandler\('Length of output: 444
Script:
#!/bin/bash # Description: Verify that the functions made private are not called externally. # Test: Search for external calls to the private functions. # Expected result: No external calls found. # Search for external calls to _resetApproval rg '_resetApproval\(' --glob '*.sol' # Search for external calls to _transferFromToAssetHandler rg '_transferFromToAssetHandler\(' --glob '*.sol' # Search for external calls to _transferToAssetHandler\(' --glob '*.sol'Length of output: 1444
v2/test/ZetaConnectorNonNative.t.sol (5)
174-174
: Verify the appropriateness ofarbitraryCallMessageContext
in this testIn
testWithdrawAndCallReceiveERC20
, you're passingarbitraryCallMessageContext
withsender: address(0)
towithdrawAndCall
. Ensure that usingaddress(0)
as the sender is suitable for this test case. If the test aims to simulate a specific sender, consider creating aMessageContext
with a meaningfulsender
address to reflect realistic scenarios.
193-226
: Great addition of comprehensive test forwithdrawAndCall
withMessageContext
The
testWithdrawAndCallReceiveOnCall
function effectively tests thewithdrawAndCall
method with the newMessageContext
parameter. It validates that the correct events are emitted and that token balances remain unchanged as expected when handlingonCall
. This enhances the test coverage for the updated functionality.
228-238
: Ensure correct error handling for unauthorized calls toonCall
In
testWithdrawAndCallReceiveOnCallTNotAllowedWithArbitraryCall
, the test expects a revert withNotAllowedToCallOnCall.selector
. Verify that theNotAllowedToCallOnCall
error is properly defined and used consistently in the contract. Additionally, confirm that the test accurately simulates an unauthorized call scenario toonCall
, ensuring the contract's security measures are effectively tested.
268-268
: Verify theMessageContext
used intestWithdrawAndCallReceiveNoParams
In this test, you're using
arbitraryCallMessageContext
withsender: address(0)
. Ensure that this context is appropriate for the test scenario. If the test requires a specific sender or aims to simulate a particular context, consider initializing aMessageContext
with the relevantsender
address within the test function.
306-306
: EnsureMessageContext
accurately represents the test scenarioIn
testWithdrawAndCallReceiveERC20Partial
, thearbitraryCallMessageContext
is used with a default sender. To enhance the accuracy of the test, verify that theMessageContext
reflects the intended sender for this scenario. Initializing a specificMessageContext
within the test can improve clarity and prevent unintended interactions.v2/test/ZetaConnectorNative.t.sol (6)
232-265
: Review the new testtestWithdrawAndCallReceiveOnCall()
for completeness.The new test function appears to correctly verify the
withdrawAndCall
functionality when receiving anonCall
message. Ensure that all relevant assertions are included, and consider adding edge cases to thoroughly test the behavior.
305-305
: Review the usage ofarbitraryCallMessageContext
intestWithdrawAndCallReceiveNoParams()
.Check whether using
arbitraryCallMessageContext
withsender
set toaddress(0)
is suitable for this test, or if a specificMessageContext
should be provided to match the test's intent and improve clarity.Run the following script to ensure consistency in
MessageContext
usage across tests:#!/bin/bash # Description: List all `withdrawAndCall` calls and the `MessageContext` passed. # Search for `withdrawAndCall` invocations and extract the `MessageContext` argument rg --type solidity 'withdrawAndCall\(' -A 1 | rg 'MessageContext\([^)]+\)'Expected Result: Verify that the
MessageContext
passed towithdrawAndCall
matches each test case's requirements and that usingarbitraryCallMessageContext
is intentional and appropriate.
341-341
: Check the correctness ofMessageContext
intestWithdrawAndCallReceiveERC20Partial()
.Ensure that
arbitraryCallMessageContext
is appropriate for this test, and consider whether a specificMessageContext
should be used to accurately simulate the test conditions and improve test clarity.Run the following script to confirm
MessageContext
usage in this test:#!/bin/bash # Description: Verify `MessageContext` in `testWithdrawAndCallReceiveERC20Partial`. # Extract the `MessageContext` parameter used in the test function rg --type solidity -A 10 'function testWithdrawAndCallReceiveERC20Partial\(\)' | rg 'withdrawAndCall\(' -A 1Expected Result: Review the extracted
MessageContext
and ensure it is appropriate for the test scenario, confirming that the context aligns with the intended behavior being tested.
213-213
: Verify the appropriateness of usingarbitraryCallMessageContext
intestWithdrawAndCallReceiveERC20()
.In this test,
arbitraryCallMessageContext
hassender
set toaddress(0)
. Ensure that this context aligns with the expected behavior of the test, and that usingaddress(0)
does not affect the functionality being tested.Run the following script to check all instances where
arbitraryCallMessageContext
is used and verify thesender
value:Expected Result: Confirm that
arbitraryCallMessageContext
is appropriate in each test case and that thesender
field is correctly set for the intended test scenarios.✅ Verification successful
Verification Successful:
arbitraryCallMessageContext
Usage is AppropriateThe use of
arbitraryCallMessageContext
withsender
set toaddress(0)
aligns with the intended test scenarios and does not negatively impact the functionality being tested.
- Verified in multiple test files:
v2/test/ZetaConnectorNative.t.sol
v2/test/ZetaConnectorNonNative.t.sol
v2/test/GatewayEVMZEVM.t.sol
v2/test/GatewayEVM.t.sol
v2/test/ERC20Custody.t.sol
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Find usages of `arbitraryCallMessageContext` and display the context where it is used. # Search for `arbitraryCallMessageContext` assignments and usages in Solidity files rg --type solidity -A 2 'arbitraryCallMessageContext'Length of output: 86
Script:
#!/bin/bash # Description: Find usages of `arbitraryCallMessageContext` and display the context where it is used. # Search for `arbitraryCallMessageContext` in Solidity files with .sol extension rg --glob '*.sol' -A 2 'arbitraryCallMessageContext'Length of output: 9944
267-277
: Verify error handling intestWithdrawAndCallReceiveOnCallTNotAllowedWithArbitraryCall()
.Confirm that the
vm.expectRevert
is correctly catching theNotAllowedToCallOnCall
error and that the test accurately reflects the scenario where an arbitrary call toonCall
is disallowed.Run the following script to find all definitions and usages of
NotAllowedToCallOnCall
:Expected Result: Verify that
NotAllowedToCallOnCall
is correctly defined as an error and that it is appropriately used in both the contract and the test to ensure the test behaves as expected.✅ Verification successful
Error Handling Verified Successfully. The
vm.expectRevert(NotAllowedToCallOnCall.selector)
correctly catches theNotAllowedToCallOnCall
error, ensuring that arbitrary calls toonCall
are properly disallowed.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Find occurrences of `NotAllowedToCallOnCall` in the codebase. # Search for `NotAllowedToCallOnCall` definitions and usages in Solidity files rg --type solidity 'NotAllowedToCallOnCall'Length of output: 143
Script:
#!/bin/bash # Description: Find occurrences of `NotAllowedToCallOnCall` in Solidity (.sol) files. # Search for `NotAllowedToCallOnCall` in files with .sol extension rg 'NotAllowedToCallOnCall' --glob '*.sol'Length of output: 656
287-287
: EnsurearbitraryCallMessageContext
is appropriate intestWithdrawAndCallReceiveERC20FailsIfSenderIsNotWithdrawer()
.In this test, verify that using
arbitraryCallMessageContext
is suitable for testing the failure case where the sender lacks theWITHDRAWER_ROLE
. Ensure that the context does not unintentionally affect the test outcome.Run the following script to review the context of
withdrawAndCall
calls in failure tests:Expected Result: Confirm that in failure tests, the
MessageContext
parameters are appropriate for the scenarios being tested and do not interfere with the focus of the test.v2/test/GatewayEVM.t.sol (1)
189-190
: Correct usage ofMessageContext.sender
intestForwardCallToReceiveOnCallUsingAuthCall
The test properly initializes
sender
with a specific address and includes it in theMessageContext
. This accurately simulates the scenario where the sender is a particular address, ensuring the test reflects the expected behavior.Also applies to: 194-194
v2/test/ERC20Custody.t.sol (10)
38-38
: Verify initialization ofarbitraryCallMessageContext.sender
Initializing
arbitraryCallMessageContext.sender
withaddress(0)
may cause unexpected behavior if downstream logic expects a valid non-zero address. Please confirm that usingaddress(0)
is intentional and that all contract functions handle this case appropriately.
286-286
: Test correctly expects revert for unauthorized accountThe test properly checks that a revert occurs when an unauthorized account (
owner
) attempts to callwithdrawAndCall
, ensuring access control is enforced.
296-296
: Test correctly handles zero amount caseThe test accurately verifies that calling
withdrawAndCall
with an amount of zero reverts withInsufficientERC20Amount
, confirming proper input validation.
306-306
: Test correctly handles zero address receiverThe test ensures that invoking
withdrawAndCall
with a zero address as the receiver reverts withZeroAddress
, which is essential for preventing token loss.
343-373
: Review oftestForwardCallToReceiveOnCallThroughCustody
The test correctly initializes
MessageContext
with a specificsender
and verifies thatwithdrawAndCall
functions as expected. All assertions and emitted events are properly validated.
375-384
: Test correctly verifiesNotAllowedToCallOnCall
revertThe test accurately checks that attempting to call
onCall
viawithdrawAndCall
witharbitraryCallMessageContext
reverts withNotAllowedToCallOnCall
, ensuring restricted functions cannot be called arbitrarily.
386-393
: Test correctly verifiesNotAllowedToCallOnRevert
revertThis test ensures that calling
onRevert
throughwithdrawAndCall
witharbitraryCallMessageContext
appropriately reverts withNotAllowedToCallOnRevert
, maintaining contract security.
402-402
: Test correctly expects revert for unauthorized accountSimilar to earlier, the test validates that an unauthorized account cannot invoke
withdrawAndCall
, reinforcing access control mechanisms.
412-412
: Test correctly handles zero amount caseThe test confirms that providing an amount of zero to
withdrawAndCall
results in a revert withInsufficientERC20Amount
, highlighting proper input checks.
462-462
: Test correctly verifiesNotWhitelisted
revertThe test ensures that calling
withdrawAndCall
with a token that has been unwhitelisted reverts withNotWhitelisted
, enforcing token whitelist constraints.v2/test/utils/upgrades/ZetaConnectorNonNativeUpgradeTest.sol (2)
91-91
:⚠️ Potential issueConfirm correct usage of
gateway.executeWithERC20
withmessageContext
In the call to
gateway.executeWithERC20(messageContext, address(zetaToken), to, amount, data);
, ensure that thegateway
contract'sexecuteWithERC20
function acceptsMessageContext
as the first parameter. If thegateway
contract or its interface has not been updated accordingly, this could result in a mismatch and potential runtime errors.Run the following script to check the definition of
executeWithERC20
in thegateway
contract:#!/bin/bash # Description: Verify that `gateway.executeWithERC20` accepts `MessageContext` as the first parameter. # Search for the definition of `executeWithERC20` in Solidity files # Expect: Function should have `MessageContext` as the first parameter rg --type solidity -A3 -B3 'function executeWithERC20\('
132-132
: Assess the impact of changing_mintTo
visibility frominternal
toprivate
The
_mintTo
function's visibility has been changed frominternal
toprivate
. This restricts its access exclusively to theZetaConnectorNonNativeUpgradeTest
contract. Ensure that no derived contracts or external functions rely on_mintTo
. Changing visibility could break functionality in contracts that inherit from this contract.Run the following script to identify any external usages of
_mintTo
:#!/bin/bash # Description: Check for any calls to `_mintTo` outside of the current contract. # Search for calls to `_mintTo` in Solidity files excluding the current file # Expect: No occurrences of `_mintTo` being used outside this contract rg --type solidity '_mintTo\(' --glob '!v2/test/utils/upgrades/ZetaConnectorNonNativeUpgradeTest.sol'
/// @param messageContext Message context containing sender. | ||
/// @param to The address to withdraw tokens to. | ||
/// @param amount The amount of tokens to withdraw. | ||
/// @param data The calldata to pass to the contract call. | ||
/// @param internalSendHash A hash used for internal tracking of the transaction. | ||
/// @dev This function can only be called by the TSS address. | ||
function withdrawAndCall( | ||
MessageContext calldata messageContext, |
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.
💡 Codebase verification
Action Required: Update All withdrawAndCall
Calls
Multiple instances of withdrawAndCall
were found across the codebase. Please ensure that each call includes the new MessageContext
parameter to maintain consistency and functionality.
- Review and update all identified calls in the output to match the updated function signature.
- Ensure that the
MessageContext
is correctly constructed and passed in each case.
🔗 Analysis chain
LGTM: Updated withdrawAndCall
function signature and comment.
The function signature has been correctly updated to include the new MessageContext
parameter, and the function comment has been appropriately updated to describe this new parameter.
To ensure consistency across the codebase, please run the following script to check for any calls to withdrawAndCall
that might need updating:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for calls to withdrawAndCall that might need updating
# Search for calls to withdrawAndCall
rg --type solidity 'withdrawAndCall\s*\(' -C 3
Length of output: 105
Script:
#!/bin/bash
# Description: Check for calls to withdrawAndCall that might need updating
# Search for calls to withdrawAndCall across all files
rg 'withdrawAndCall\s*\(' -C 3
Length of output: 106857
/// @param messageContext Message context containing sender and arbitrary call flag. | ||
/// @param token The address of the ERC20 token. | ||
/// @param to The address of the contract to call. | ||
/// @param amount The amount of tokens to transfer. | ||
/// @param data The calldata to pass to the contract call. |
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.
Update Documentation to Match MessageContext
Structure
The documentation for the messageContext
parameter mentions that it contains "sender and arbitrary call flag," but the MessageContext
struct only includes address sender;
. Please update the documentation to accurately reflect the actual structure of MessageContext
or include the "arbitrary call flag" in the struct if necessary.
If the "arbitrary call flag" is not required, apply this diff to update the documentation:
/// @param messageContext Message context containing sender and arbitrary call flag.
+/// @param messageContext Message context containing the sender address.
📝 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.
/// @param messageContext Message context containing sender and arbitrary call flag. | |
/// @param token The address of the ERC20 token. | |
/// @param to The address of the contract to call. | |
/// @param amount The amount of tokens to transfer. | |
/// @param data The calldata to pass to the contract call. | |
/// @param messageContext Message context containing the sender address. | |
/// @param token The address of the ERC20 token. | |
/// @param to The address of the contract to call. | |
/// @param amount The amount of tokens to transfer. | |
/// @param data The calldata to pass to the contract call. |
_grantRole(PAUSER_ROLE, tssAddress_); | ||
_grantRole(WITHDRAWER_ROLE, tssAddress_); | ||
_grantRole(WHITELISTER_ROLE, admin_); | ||
_grantRole(WHITELISTER_ROLE, tssAddress_); |
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.
💡 Codebase verification
Security Concern: Multiple Critical Roles Assigned to tssAddress_
The tssAddress_
is granted the following roles:
PAUSER_ROLE
WITHDRAWER_ROLE
WHITELISTER_ROLE
TSS_ROLE
Granting these roles provides significant permissions, including the ability to pause the contract and withdraw funds. Ensure that tssAddress_
is a trusted entity with appropriate security measures in place.
🔗 Analysis chain
Security Concern: Role Assignments to tssAddress_
The tssAddress_
is being granted the PAUSER_ROLE
, WITHDRAWER_ROLE
, and WHITELISTER_ROLE
:
_grantRole(PAUSER_ROLE, tssAddress_);
_grantRole(WITHDRAWER_ROLE, tssAddress_);
_grantRole(WHITELISTER_ROLE, admin_);
_grantRole(WHITELISTER_ROLE, tssAddress_);
Granting the PAUSER_ROLE
to the TSS address allows it to pause and unpause the contract, which is a critical operation. Ensure that this level of access is intended and that the TSS address is trusted to manage these roles.
Run the following script to review all role assignments to tssAddress_
and assess potential security implications:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find all instances where roles are granted to tssAddress_
# Test: Ensure only intended roles are granted to tssAddress_
rg --type solidity $'grantRole\\(.+, tssAddress_\\)'
Length of output: 156
Script:
#!/bin/bash
# Description: Find all instances where roles are granted to tssAddress_ in Solidity files
# Test: Ensure only intended roles are granted to tssAddress_
rg --glob "*.sol" 'grantRole\(.+, tssAddress_\)'
Length of output: 1195
if (messageContext.sender == address(0)) { | ||
result = _executeArbitraryCall(destination, data); | ||
} else { | ||
result = _executeAuthenticatedCall(messageContext, destination, data); | ||
} |
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.
🛠️ Refactor suggestion
Consider using an explicit flag to indicate call type instead of checking messageContext.sender
Currently, the code distinguishes between arbitrary and authenticated calls by checking if messageContext.sender == address(0)
. While this approach works, it relies on a special value for the sender address, which can be less readable and might lead to errors if not handled carefully.
Consider introducing an explicit boolean flag in MessageContext
, such as isAuthenticated
, to make the distinction clearer and improve code readability:
struct MessageContext {
address sender;
bool isAuthenticated;
}
Then update the condition:
-if (messageContext.sender == address(0)) {
+if (!messageContext.isAuthenticated) {
result = _executeArbitraryCall(destination, data);
} else {
result = _executeAuthenticatedCall(messageContext, destination, data);
}
function _executeArbitraryCall(address destination, bytes calldata data) private returns (bytes memory) { | ||
_revertIfOnCallOrOnRevert(data); | ||
(bool success, bytes memory result) = destination.call{ value: msg.value }(data); | ||
if (!success) revert ExecutionFailed(); | ||
|
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.
Ensure correct extraction of function selector in _revertIfOnCallOrOnRevert
The assembly code in _revertIfOnCallOrOnRevert
may not correctly extract the function selector from data
. Consider using safer methods to extract the function selector without using assembly.
You can replace the assembly code with Solidity's built-in functions:
function _revertIfOnCallOrOnRevert(bytes calldata data) private pure {
if (data.length >= 4) {
- bytes4 functionSelector;
- assembly {
- functionSelector := calldataload(data.offset)
- }
+ bytes4 functionSelector = bytes4(data[:4]);
if (functionSelector == Callable.onCall.selector) {
revert NotAllowedToCallOnCall();
}
if (functionSelector == Revertable.onRevert.selector) {
revert NotAllowedToCallOnRevert();
}
}
}
This approach avoids direct memory manipulation and enhances code safety and readability.
Also applies to: 452-468
@@ -240,7 +241,7 @@ | |||
|
|||
vm.expectRevert(EnforcedPause.selector); | |||
vm.prank(tssAddress); | |||
custody.withdrawAndCall(address(receiver), address(token), amount, data); | |||
custody.withdrawAndCall(arbitraryCallMessageContext, address(receiver), address(token), amount, data); |
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.
🛠️ Refactor suggestion
Use a realistic MessageContext.sender
in tests
As above, updating arbitraryCallMessageContext.sender
to a valid address can improve test accuracy by reflecting actual usage conditions.
@@ -256,7 +257,7 @@ | |||
vm.expectEmit(true, true, true, true, address(custody)); | |||
emit WithdrawnAndCalled(address(receiver), address(token), amount, data); | |||
vm.prank(tssAddress); | |||
custody.withdrawAndCall(address(receiver), address(token), amount, data); | |||
custody.withdrawAndCall(arbitraryCallMessageContext, address(receiver), address(token), amount, data); |
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.
🛠️ Refactor suggestion
Use a realistic MessageContext.sender
in tests
Again, consider setting arbitraryCallMessageContext.sender
to a meaningful address to enhance the effectiveness of this test.
@@ -320,7 +321,7 @@ | |||
vm.expectEmit(true, true, true, true, address(custody)); | |||
emit WithdrawnAndCalled(address(receiver), address(token), amount, data); | |||
vm.prank(tssAddress); | |||
custody.withdrawAndCall(address(receiver), address(token), amount, data); | |||
custody.withdrawAndCall(arbitraryCallMessageContext, address(receiver), address(token), amount, data); |
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.
🛠️ Refactor suggestion
Use a realistic MessageContext.sender
in tests
In this test, consider assigning a valid address to arbitraryCallMessageContext.sender
to more accurately simulate typical usage and enhance test coverage.
@@ -373,7 +426,7 @@ | |||
vm.expectEmit(true, true, true, true, address(custody)); | |||
emit WithdrawnAndCalled(address(receiver), address(token), amount, data); | |||
vm.prank(tssAddress); | |||
custody.withdrawAndCall(address(receiver), address(token), amount, data); | |||
custody.withdrawAndCall(arbitraryCallMessageContext, address(receiver), address(token), amount, data); |
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.
🛠️ Refactor suggestion
Use a realistic MessageContext.sender
in tests
In testForwardCallToReceiveNoParamsThroughCustody
, consider setting arbitraryCallMessageContext.sender
to a valid address to reflect real-world use cases and improve test reliability.
/// @param messageContext Message context containing sender. | ||
/// @param to The address to withdraw tokens to. | ||
/// @param amount The amount of tokens to withdraw. | ||
/// @param data The calldata to pass to the contract call. | ||
/// @param internalSendHash A hash used for internal tracking of the transaction. | ||
/// @dev This function can only be called by the TSS address, and mints if supply is not reached. | ||
function withdrawAndCall( | ||
MessageContext calldata messageContext, |
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.
💡 Codebase verification
Function withdrawAndCall
does not correctly override the base contract. The override
keyword is missing in the function definition.
- File:
v2/test/utils/upgrades/ZetaConnectorNonNativeUpgradeTest.sol
, Lines: 68-75
🔗 Analysis chain
Ensure function signature correctly overrides base contract
The withdrawAndCall
function now includes MessageContext calldata messageContext
as a parameter and is marked as override
. Please verify that the function signature matches the one in the base contract or interface. A mismatch can lead to compilation errors or unexpected behavior during contract interactions.
Run the following script to verify that the overridden function signatures align:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the `withdrawAndCall` function signature matches in base contracts/interfaces.
# Search for the `withdrawAndCall` function definitions in Solidity files
# Expect: Function signatures should include `MessageContext` as the first parameter
rg --type solidity -A3 -B3 'function withdrawAndCall\('
Length of output: 136
Script:
#!/bin/bash
# Description: Verify that the `withdrawAndCall` function signature matches in base contracts/interfaces.
# Search for the `withdrawAndCall` function definitions in Solidity files
# Expect: Function signatures should include `MessageContext` as the first parameter
rg --glob '*.sol' -A3 -B3 'function withdrawAndCall\('
Length of output: 10212
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: 2
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (9)
v2/docs/src/contracts/evm/GatewayEVM.sol/contract.GatewayEVM.md
is excluded by!v2/docs/**
v2/pkg/erc20custody.t.sol/erc20custodytest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevm.sol/gatewayevm.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevm.t.sol/gatewayevminboundtest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevm.t.sol/gatewayevmtest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevmzevm.t.sol/gatewayevmzevmtest.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornative.t.sol/zetaconnectornativetest.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornonnative.t.sol/zetaconnectornonnativetest.go
is excluded by!v2/pkg/**
v2/types/factories/GatewayEVM__factory.ts
is excluded by!v2/types/**
📒 Files selected for processing (1)
- v2/contracts/evm/GatewayEVM.sol (4 hunks)
🧰 Additional context used
// Execute the call on the target contract | ||
// if sender is provided in messageContext call is authenticated and target is Callable.onCall | ||
// otherwise, call is arbitrary | ||
if (messageContext.sender == address(0)) { | ||
result = _executeArbitraryCall(destination, data); | ||
} else { | ||
result = _executeAuthenticatedCall(messageContext, destination, data); | ||
} |
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.
🛠️ Refactor suggestion
Consider refactoring duplicated conditional logic into a private function
The conditional logic that checks messageContext.sender == address(0)
to decide between _executeArbitraryCall
and _executeAuthenticatedCall
is duplicated in both the execute
and executeWithERC20
functions. Extracting this logic into a private helper function can improve maintainability and reduce code duplication.
if (messageContext.sender == address(0)) { | ||
_executeArbitraryCall(to, data); | ||
} else { | ||
_executeAuthenticatedCall(messageContext, to, data); | ||
} |
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.
💡 Codebase verification
Return value of executeWithERC20
is not being captured
The return value of executeWithERC20
is not captured or returned in any of its calls. To ensure proper logging, error handling, or further processing, consider capturing the execution result as done in the execute
function.
🔗 Analysis chain
Verify if the execution result in executeWithERC20
should be captured
In the execute
function, the result of the call is captured and returned to the caller. However, in executeWithERC20
, the result of _executeArbitraryCall
or _executeAuthenticatedCall
is neither captured nor returned. If the execution result is important for logging, error handling, or further processing, consider capturing and handling it similarly in executeWithERC20
.
You can run the following script to check if any usage or overrides of executeWithERC20
expect a return value:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for usages of `executeWithERC20` and check if the return value is utilized.
# Find all Solidity files that call `executeWithERC20`
rg --type solidity 'executeWithERC20\('
# Check if any derived contracts override `executeWithERC20` with a return value
rg --type solidity 'function executeWithERC20\('
Length of output: 158
Script:
#!/bin/bash
# Description: Search for usages of `executeWithERC20` and check if the return value is utilized within Solidity files.
# Find all Solidity files that call `executeWithERC20`
rg 'executeWithERC20\(' --glob '*.sol'
# Check if any derived contracts override `executeWithERC20` with a return value
rg 'function executeWithERC20\(' --glob '*.sol'
Length of output: 1554
Script:
#!/bin/bash
# Description: Check if the return values of `executeWithERC20` are captured or utilized within Solidity files.
# Search for `executeWithERC20` calls that are part of an assignment
rg '=\s*executeWithERC20\(' --glob '*.sol'
# Search for `executeWithERC20` calls that are returned directly
rg 'return\s+executeWithERC20\(' --glob '*.sol'
# Search for `executeWithERC20` calls used in expressions (e.g., inside require or assert)
rg '(require|assert)\s*\(\s*executeWithERC20\(' --glob '*.sol'
Length of output: 159
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: 0
🧹 Outside diff range and nitpick comments (3)
v2/test/ERC20Custody.t.sol (3)
38-38
: Consider using a realistic sender address forarbitraryCallMessageContext
The
arbitraryCallMessageContext
is initialized withaddress(0)
as the sender. For more robust testing, consider using a non-zero address that better represents a realistic scenario. This could help catch potential issues related to sender validation in your contract.You could modify the line as follows:
- MessageContext arbitraryCallMessageContext = MessageContext({ sender: address(0) }); + MessageContext arbitraryCallMessageContext = MessageContext({ sender: address(0x1234) });
343-373
: LGTM! Comprehensive test forwithdrawAndCall
with customMessageContext
This new test function thoroughly checks the behavior of
withdrawAndCall
when called with a specificMessageContext
. It verifies token balances, event emissions, and proper handling of the message context.Consider adding a test case where the
sender
inMessageContext
is set toaddress(0)
to ensure the contract handles this edge case correctly.
386-393
: LGTM! Crucial security check for preventing arbitraryonRevert
invocationsThis test function effectively verifies that direct calls to
onRevert
throughwithdrawAndCall
are not allowed when using an arbitrary call context. This is a critical security measure to prevent potential vulnerabilities.Consider adding a similar test for other sensitive functions (if any) that should not be callable through
withdrawAndCall
to ensure comprehensive coverage of this security measure.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
⛔ Files ignored due to path filters (15)
v2/docs/src/contracts/evm/ZetaConnectorNative.sol/contract.ZetaConnectorNative.md
is excluded by!v2/docs/**
v2/pkg/erc20custody.t.sol/erc20custodytest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevm.t.sol/gatewayevminboundtest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevm.t.sol/gatewayevmtest.go
is excluded by!v2/pkg/**
v2/pkg/gatewayevmzevm.t.sol/gatewayevmzevmtest.go
is excluded by!v2/pkg/**
v2/pkg/receiverevm.sol/receiverevm.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornative.sol/zetaconnectornative.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornative.t.sol/zetaconnectornativetest.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornativeupgradetest.sol/zetaconnectornativeupgradetest.go
is excluded by!v2/pkg/**
v2/pkg/zetaconnectornonnative.t.sol/zetaconnectornonnativetest.go
is excluded by!v2/pkg/**
v2/types/ZetaConnectorNative.ts
is excluded by!v2/types/**
v2/types/ZetaConnectorNativeUpgradeTest.ts
is excluded by!v2/types/**
v2/types/factories/ReceiverEVM__factory.ts
is excluded by!v2/types/**
v2/types/factories/ZetaConnectorNativeUpgradeTest__factory.ts
is excluded by!v2/types/**
v2/types/factories/ZetaConnectorNative__factory.ts
is excluded by!v2/types/**
📒 Files selected for processing (4)
- v2/contracts/evm/ZetaConnectorNative.sol (2 hunks)
- v2/test/ERC20Custody.t.sol (12 hunks)
- v2/test/utils/ReceiverEVM.sol (1 hunks)
- v2/test/utils/upgrades/ZetaConnectorNativeUpgradeTest.sol (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- v2/contracts/evm/ZetaConnectorNative.sol
- v2/test/utils/ReceiverEVM.sol
- v2/test/utils/upgrades/ZetaConnectorNativeUpgradeTest.sol
🧰 Additional context used
🔇 Additional comments (4)
v2/test/ERC20Custody.t.sol (4)
207-207
: LGTM! Consider verifying the impact ofarbitraryCallMessageContext
The update correctly incorporates the new
MessageContext
parameter in thewithdrawAndCall
function call. This change aligns with the updated function signature.To ensure this change doesn't affect the test's behavior unexpectedly, you might want to verify that the
arbitraryCallMessageContext
is properly handled within thewithdrawAndCall
function. Consider adding assertions to check if the sender from the context is used as expected in the contract logic.
244-244
: LGTM!arbitraryCallMessageContext
correctly incorporatedThe
withdrawAndCall
function calls have been properly updated to include thearbitraryCallMessageContext
parameter. This change maintains the test's integrity while adapting to the new function signature.Also applies to: 260-260
375-384
: LGTM! Important security check for preventing arbitraryonCall
invocationsThis test function effectively verifies that direct calls to
onCall
throughwithdrawAndCall
are not allowed when using an arbitrary call context. This is an important security measure to prevent potential vulnerabilities.
286-286
: LGTM! Consistent application ofarbitraryCallMessageContext
The
withdrawAndCall
function calls across various test cases have been consistently updated to include thearbitraryCallMessageContext
parameter. This change maintains the integrity of the tests while adapting to the new function signature.To ensure these changes haven't inadvertently altered the behavior of the tests, consider running a diff of the test results before and after these modifications. This will help verify that the introduction of
arbitraryCallMessageContext
hasn't changed the expected outcomes of these tests.Also applies to: 296-296, 306-306, 324-324, 402-402, 412-412, 429-429, 462-462
// Execute the call on the target contract | ||
// if sender is provided in messageContext call is authenticated and target is Callable.onCall | ||
// otherwise, call is arbitrary | ||
if (messageContext.sender == address(0)) { |
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.
nit: this can cause problems to developer experience if not properly documented what it means to fill or not the sender.
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.
this part is called by protocol, but i see your point, i think currently comment explain what its doing: sender = authenticated call, no sender = arbitrary call
when devs use this feature, they would set up callOptions.isArbitrary field on zevm side, so there is more important from devex side of things
Summary by CodeRabbit
Release Notes
New Features
MessageContext
parameter in multiple contract functions for enhanced context during withdrawals and executions.Bug Fixes
Tests