Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: connector and revert unit tests #244

Merged
merged 20 commits into from
Jul 23, 2024
Merged

Conversation

skosito
Copy link
Contributor

@skosito skosito commented Jul 22, 2024

  • adds tests for revert and connector
  • fixes couple of bugs during testing
  • adds more tests for existing specs

Summary by CodeRabbit

  • New Features

    • Enhanced token transfer capabilities in the GatewayEVM contract with improved error handling and transfer logic.
    • New ReceivedRevert event added to improve event tracking in the IReceiverEVM interface.
    • receiveERC20Partial function introduced, allowing partial token transfers.
    • New withdrawAndRevert functions added to multiple contracts for better token withdrawal handling and error management.
    • New ContextDataRevert event in the TestZContract for better cross-chain interaction management.
  • Bug Fixes

    • Improved clarity and traceability of withdrawal events in the GatewayZEVM contract.
  • Tests

    • Comprehensive test suites added for ZetaConnectorNative and ZetaConnectorNonNative contracts to validate withdrawal functionalities.

Copy link
Contributor

coderabbitai bot commented Jul 22, 2024

Walkthrough

The recent updates enhance the functionality and robustness of various smart contracts within the EVM ecosystem, focusing on token management, error handling, and event logging. Key modifications include the introduction of new functions for withdrawals, refined error messages, and improved event emissions for better tracking. These changes reflect a modular and efficient design, particularly for ERC20 token operations, ensuring a more powerful and adaptable framework.

Changes

File Path Change Summary
contracts/prototypes/evm/GatewayEVM.sol Updated error handling for ERC20 token transfers and modified logic to transfer the remaining balance.
contracts/prototypes/evm/IReceiverEVM.sol Added ReceivedRevert event for enhanced error tracking.
contracts/prototypes/evm/ReceiverEVM.sol Implemented the IReceiverEVMEvents interface, added receiveERC20Partial, and onRevert functions for improved functionality.
contracts/prototypes/evm/ZetaConnector*.sol Introduced withdrawAndRevert function across multiple contracts for enhanced withdrawal handling.
contracts/prototypes/zevm/TestZContract.sol Added ContextDataRevert event for improved handling of cross-chain calls.
lib/types.ts Updated ParamSymbol type to include new cryptocurrency symbols.
testFoundry/* Introduced new test contracts for ZetaConnectorNative and ZetaConnectorNonNative, improving test coverage.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant GatewayEVM
    participant ZetaConnectorNative

    User->>GatewayEVM: Initiate ERC20 transfer
    GatewayEVM->>ZetaConnectorNative: Execute token withdrawal and revert
    ZetaConnectorNative-->>GatewayEVM: Confirm withdrawal success
    GatewayEVM-->>User: Notify transfer complete
Loading

🐇 In a world where tokens flow,
New paths of transfer start to glow.
With events that catch the eye,
And functions that leap and fly!
Robust and swift, our code's a delight,
In the garden of contracts, everything feels right! 🌼✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@codecov-commenter
Copy link

codecov-commenter commented Jul 22, 2024

Codecov Report

Attention: Patch coverage is 96.29630% with 1 line in your changes missing coverage. Please review.

Project coverage is 61.08%. Comparing base (b921999) to head (b3485b9).

Files Patch % Lines
contracts/zevm/WZETA.sol 90.90% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #244       +/-   ##
===========================================
+ Coverage   43.65%   61.08%   +17.42%     
===========================================
  Files          14       16        +2     
  Lines         339      388       +49     
  Branches       92      104       +12     
===========================================
+ Hits          148      237       +89     
+ Misses        191      151       -40     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@skosito skosito linked an issue Jul 22, 2024 that may be closed by this pull request
@skosito skosito marked this pull request as ready for review July 22, 2024 21:58
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: 1

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b921999 and 9a299da.

Files ignored due to path filters (32)
  • data/addresses.mainnet.json is excluded by !data/**
  • pkg/contracts/prototypes/evm/gatewayevm.sol/gatewayevm.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/gatewayevmupgradetest.sol/gatewayevmupgradetest.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/ireceiverevm.sol/ireceiverevmevents.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/receiverevm.sol/receiverevm.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/zetaconnectornative.sol/zetaconnectornative.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/zetaconnectornewbase.sol/zetaconnectornewbase.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/zetaconnectornonnative.sol/zetaconnectornonnative.go is excluded by !pkg/**
  • pkg/contracts/prototypes/zevm/gatewayzevm.sol/gatewayzevm.go is excluded by !pkg/**
  • pkg/contracts/prototypes/zevm/igatewayzevm.sol/igatewayzevmerrors.go is excluded by !pkg/**
  • pkg/contracts/prototypes/zevm/senderzevm.sol/senderzevm.go is excluded by !pkg/**
  • pkg/contracts/prototypes/zevm/testzcontract.sol/testzcontract.go is excluded by !pkg/**
  • pkg/contracts/zevm/wzeta.sol/weth9.go is excluded by !pkg/**
  • typechain-types/contracts/prototypes/evm/IReceiverEVM.sol/IReceiverEVMEvents.ts is excluded by !typechain-types/**
  • typechain-types/contracts/prototypes/evm/ReceiverEVM.ts is excluded by !typechain-types/**
  • typechain-types/contracts/prototypes/evm/ZetaConnectorNative.ts is excluded by !typechain-types/**
  • typechain-types/contracts/prototypes/evm/ZetaConnectorNewBase.ts is excluded by !typechain-types/**
  • typechain-types/contracts/prototypes/evm/ZetaConnectorNonNative.ts is excluded by !typechain-types/**
  • typechain-types/contracts/prototypes/zevm/TestZContract.ts is excluded by !typechain-types/**
  • typechain-types/contracts/zevm/WZETA.sol/WETH9.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/GatewayEVMUpgradeTest__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/GatewayEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/IReceiverEVM.sol/IReceiverEVMEvents__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/ReceiverEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/ZetaConnectorNative__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/ZetaConnectorNewBase__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/ZetaConnectorNonNative__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/zevm/GatewayZEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/zevm/IGatewayZEVM.sol/IGatewayZEVMErrors__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/zevm/SenderZEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/zevm/TestZContract__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/zevm/WZETA.sol/WETH9__factory.ts is excluded by !typechain-types/**
Files selected for processing (16)
  • contracts/prototypes/evm/GatewayEVM.sol (3 hunks)
  • contracts/prototypes/evm/IReceiverEVM.sol (1 hunks)
  • contracts/prototypes/evm/ReceiverEVM.sol (2 hunks)
  • contracts/prototypes/evm/ZetaConnectorNative.sol (1 hunks)
  • contracts/prototypes/evm/ZetaConnectorNewBase.sol (2 hunks)
  • contracts/prototypes/evm/ZetaConnectorNonNative.sol (1 hunks)
  • contracts/prototypes/zevm/GatewayZEVM.sol (3 hunks)
  • contracts/prototypes/zevm/IGatewayZEVM.sol (1 hunks)
  • contracts/prototypes/zevm/TestZContract.sol (2 hunks)
  • contracts/zevm/WZETA.sol (1 hunks)
  • lib/types.ts (1 hunks)
  • testFoundry/GatewayEVM.t.sol (8 hunks)
  • testFoundry/GatewayEVMZEVM.t.sol (2 hunks)
  • testFoundry/GatewayZEVM.t.sol (2 hunks)
  • testFoundry/ZetaConnectorNative.t.sol (1 hunks)
  • testFoundry/ZetaConnectorNonNative.t.sol (1 hunks)
Additional context used
Path-based instructions (10)
contracts/prototypes/evm/IReceiverEVM.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

contracts/prototypes/evm/ZetaConnectorNewBase.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

contracts/prototypes/zevm/TestZContract.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

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

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

contracts/prototypes/evm/ReceiverEVM.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

contracts/zevm/WZETA.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

contracts/prototypes/evm/ZetaConnectorNonNative.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

contracts/prototypes/evm/ZetaConnectorNative.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

contracts/prototypes/zevm/GatewayZEVM.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

contracts/prototypes/evm/GatewayEVM.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

GitHub Check: Slither
contracts/prototypes/evm/ReceiverEVM.sol

[notice] 30-35: Reentrancy vulnerabilities
Reentrancy in ReceiverEVM.receiveERC20Partial(uint256,address,address) (contracts/prototypes/evm/ReceiverEVM.sol#30-35):
External calls:
- IERC20(token).safeTransferFrom(msg.sender,destination,amount / 2) (contracts/prototypes/evm/ReceiverEVM.sol#32)
Event emitted after the call(s):
- ReceivedERC20(msg.sender,amount / 2,token,destination) (contracts/prototypes/evm/ReceiverEVM.sol#34)

Additional comments not posted (81)
contracts/prototypes/evm/IReceiverEVM.sol (1)

9-9: LGTM! New event declaration enhances event tracking.

The addition of the ReceivedRevert event improves the interface's capability to log revert-related activities, providing better error handling and state tracking.

lib/types.ts (1)

1-1: LGTM! Ensure all parts of the application handle the new symbols.

The updates to the ParamSymbol type reflect new supported cryptocurrency symbols. Verify that all relevant parts of the application are updated to handle these new symbols.

contracts/prototypes/evm/ZetaConnectorNewBase.sol (2)

19-19: LGTM! New event declaration enhances error tracking.

The addition of the WithdrawAndRevert event improves the contract's capability to log withdrawal attempts that may revert, providing better transparency and traceability.


33-33: LGTM! New function enhances error handling in withdrawal operations.

The withdrawAndRevert function enhances the contract's capability to manage withdrawal operations that may revert, ensuring more robust error handling.

contracts/prototypes/zevm/TestZContract.sol (3)

9-9: Event declaration looks good.

The new event ContextDataRevert is correctly declared and follows Solidity conventions.


34-34: Event emission change looks good.

The function correctly emits the new event ContextDataRevert, aligning with the intended use.


37-38: Receive and fallback functions look good.

The receive and fallback functions are correctly implemented to handle Ether transfers.

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

50-50: Error declaration looks good.

The new error OnlyWZETAOrFungible is correctly declared and enhances the contract's error handling capabilities.

contracts/prototypes/evm/ReceiverEVM.sol (3)

6-6: Import statement looks good.

The import statement for IReceiverEVM is correctly added and necessary for the contract's functionality.


42-45: Function implementation looks good.

The function onRevert is correctly implemented to emit the ReceivedRevert event.


47-48: Receive and fallback functions look good.

The receive and fallback functions are correctly implemented to handle Ether transfers.

contracts/zevm/WZETA.sol (8)

2-2: LGTM! Solidity version update.

The Solidity version pragma has been updated to ^0.8.0, which is appropriate for modern Solidity development.


9-12: LGTM! Event declarations update.

The event declarations have been updated to use uint256 instead of uint, aligning with best practices for handling larger numbers in Solidity.


17-17: LGTM! receive function implementation.

The receive function is correctly implemented to handle Ether deposits, adhering to Solidity best practices.


26-30: LGTM! withdraw function update.

The withdraw function has been updated to use uint256 instead of uint, aligning with best practices for handling larger numbers in Solidity.


33-34: LGTM! totalSupply function update.

The totalSupply function has been updated to use uint256 instead of uint, aligning with best practices for handling larger numbers in Solidity.


37-39: LGTM! approve function update.

The approve function has been updated to use uint256 instead of uint, aligning with best practices for handling larger numbers in Solidity.


43-43: LGTM! transfer function update.

The transfer function has been updated to use uint256 instead of uint, aligning with best practices for handling larger numbers in Solidity.


47-64: LGTM! transferFrom function update.

The transferFrom function has been updated to use uint256 instead of uint, and the allowance check has been updated to use type(uint256).max, reflecting a more modern approach to handling maximum values in Solidity.

contracts/prototypes/evm/ZetaConnectorNonNative.sol (1)

30-39: LGTM! withdrawAndRevert function implementation.

The withdrawAndRevert function is correctly implemented, facilitating the minting of zetaToken to a specified gateway address and subsequently calling a revertWithERC20 method on the gateway contract. The use of the nonReentrant modifier enhances security by preventing reentrant calls.

contracts/prototypes/evm/ZetaConnectorNative.sol (2)

32-41: LGTM! withdrawAndRevert function implementation.

The withdrawAndRevert function is correctly implemented, facilitating the transfer of zetaToken to a specified address and subsequently invoking a revert operation on a contract. The use of the nonReentrant modifier enhances security by preventing reentrant calls.


44-44: Verify the removal of the nonReentrant modifier.

The receiveTokens function has been modified by removing the nonReentrant modifier. Ensure that this change does not introduce security vulnerabilities, particularly reentrancy attacks.

contracts/prototypes/zevm/GatewayZEVM.sol (3)

82-82: LGTM! The emit statement update improves clarity.

The change from address(0) to zetaToken in the emit statement enhances the traceability of withdrawal events.


88-88: LGTM! The emit statement update improves clarity.

The change from address(0) to zetaToken in the emit statement enhances the traceability of withdrawal events.


40-43: LGTM! Ensure the receive function is tested.

The receive function includes a security check to restrict the sender to specific addresses. This is a good practice to prevent unauthorized transfers.

However, ensure that the receive function is adequately tested in your test cases.

contracts/prototypes/evm/GatewayEVM.sol (2)

88-88: LGTM! The error message update is appropriate.

The change from InsufficientETHAmount to InsufficientERC20Amount accurately reflects the context of ERC20 tokens.


101-101: LGTM! The logic update improves efficiency.

The modification to transfer the remaining balance instead of a fixed amount enhances the contract's flexibility and efficiency in handling ERC20 tokens.

testFoundry/GatewayEVMZEVM.t.sol (1)

43-43: LGTM! The type change enhances functionality.

The change to address payable allows the proxyZEVM variable to receive Ether, which is crucial for the contract's operations involving Ether transactions.

testFoundry/ZetaConnectorNative.t.sol (7)

36-57: LGTM!

The setUp function correctly initializes the testing environment.


59-72: LGTM!

The testWithdraw function correctly tests the withdraw functionality.


74-105: LGTM!

The testWithdrawAndCallReceiveERC20 function correctly tests the withdrawAndCall functionality with receiveERC20.


107-138: LGTM!

The testWithdrawAndCallReceiveNoParams function correctly tests the withdrawAndCall functionality with receiveNoParams.


140-171: LGTM!

The testWithdrawAndCallReceiveERC20Partial function correctly tests the withdrawAndCall functionality with receiveERC20Partial.


173-207: LGTM!

The testWithdrawAndRevert function correctly tests the withdrawAndRevert functionality.


173-207: LGTM!

The testWithdrawAndRevert function correctly tests the withdrawAndRevert functionality.

testFoundry/ZetaConnectorNonNative.t.sol (7)

37-59: LGTM!

The setUp function correctly initializes the testing environment.


61-74: LGTM!

The testWithdraw function correctly tests the withdraw functionality.


76-108: LGTM!

The testWithdrawAndCallReceiveERC20 function correctly tests the withdrawAndCall functionality with receiveERC20.


110-142: LGTM!

The testWithdrawAndCallReceiveNoParams function correctly tests the withdrawAndCall functionality with receiveNoParams.


144-175: LGTM!

The testWithdrawAndCallReceiveERC20Partial function correctly tests the withdrawAndCall functionality with receiveERC20Partial.


178-212: LGTM!

The testWithdrawAndRevert function correctly tests the withdrawAndRevert functionality.


178-212: LGTM!

The testWithdrawAndRevert function correctly tests the withdrawAndRevert functionality.

testFoundry/GatewayEVM.t.sol (11)

35-35: LGTM!

The WithdrawAndRevert event declaration is correct.


Line range hint 72-78:
LGTM!

The testForwardCallToReceiveNonPayable function correctly tests the execute functionality with receiveNonPayable.


79-97: LGTM!

The testForwardCallToReceivePayable function correctly tests the execute functionality with receivePayable.


Line range hint 98-103:
LGTM!

The testForwardCallToReceiveNoParams function correctly tests the execute functionality with receiveNoParams.


Line range hint 104-140:
LGTM!

The testForwardCallToReceiveERC20ThroughCustody function correctly tests the withdrawAndCall functionality with receiveERC20.


143-148: LGTM!

The testForwardCallToReceiveERC20ThroughCustodyFailsIfAmountIs0 function correctly tests the withdrawAndCall functionality with receiveERC20 when the amount is 0.


150-180: LGTM!

The testForwardCallToReceiveERC20PartialThroughCustody function correctly tests the withdrawAndCall functionality with receiveERC20Partial.


182-187: LGTM!

The testForwardCallToReceiveERC20PartialThroughCustodyFailsIfAmountIs0 function correctly tests the withdrawAndCall functionality with receiveERC20Partial when the amount is 0.


Line range hint 189-219:
LGTM!

The testForwardCallToReceiveNoParamsThroughCustody function correctly tests the withdrawAndCall functionality with receiveNoParams.


Line range hint 221-245:
LGTM!

The testWithdrawThroughCustody function correctly tests the withdraw functionality of the ERC20CustodyNew contract.


247-280: LGTM!

The testWithdrawAndRevertThroughCustody function correctly tests the withdrawAndRevert functionality of the ERC20CustodyNew contract.

testFoundry/GatewayZEVM.t.sol (28)

19-19: Verify the necessity of payable for proxy.

The proxy is now declared as a payable address. Ensure that this change is necessary for handling Ether transactions.


22-22: Verify the initialization of WETH9 token.

The WETH9 token instance is initialized. Ensure that this token is correctly integrated into the existing logic.


62-71: LGTM!

The function testWithdrawZRC20 is correctly implemented with appropriate checks and event emissions.


73-86: LGTM!

The function testWithdrawZRC20FailsIfNoAllowance is correctly implemented with appropriate checks and event emissions.


88-101: LGTM!

The function testWithdrawZRC20WithMessageFailsIfNoAllowance is correctly implemented with appropriate checks and event emissions.


105-115: LGTM!

The function testWithdrawZRC20WithMessage is correctly implemented with appropriate checks and event emissions.


117-135: LGTM!

The function testWithdrawZETA is correctly implemented with appropriate checks and event emissions.


137-157: LGTM!

The function testWithdrawZETAFailsIfNoAllowance is correctly implemented with appropriate checks and event emissions.


159-178: LGTM!

The function testWithdrawZETAWithMessage is correctly implemented with appropriate checks and event emissions.


180-200: LGTM!

The function testWithdrawZETAWithMessageFailsIfNoAllowance is correctly implemented with appropriate checks and event emissions.


Line range hint 202-210: LGTM!

The function testCall is correctly implemented with appropriate checks and event emissions.


212-212: Verify the necessity of payable for proxy.

The proxy is now declared as a payable address. Ensure that this change is necessary for handling Ether transactions.


215-215: Verify the initialization of WETH9 token.

The WETH9 token instance is initialized. Ensure that this token is correctly integrated into the existing logic.


259-268: LGTM!

The function testDeposit is correctly implemented with appropriate checks and event emissions.


270-281: LGTM!

The function testDepositFailsIfSenderNotFungibleModule is correctly implemented with appropriate checks and event emissions.


283-289: LGTM!

The function testDepositFailsIfTargetIsGateway is correctly implemented with appropriate checks and event emissions.


291-295: LGTM!

The function testDepositFailsIfTargetIsFungibleModule is correctly implemented with appropriate checks and event emissions.


298-310: LGTM!

The function testExecuteZContract is correctly implemented with appropriate checks and event emissions.


312-323: LGTM!

The function testExecuteZContractFailsIfSenderIsNotFungibleModule is correctly implemented with appropriate checks and event emissions.


325-337: LGTM!

The function testExecuteRevertZContract is correctly implemented with appropriate checks and event emissions.


339-350: LGTM!

The function testExecuteRevertZContractIfSenderIsNotFungibleModule is correctly implemented with appropriate checks and event emissions.


352-370: LGTM!

The function testDepositZRC20AndCallZContract is correctly implemented with appropriate checks and event emissions.


372-383: LGTM!

The function testDepositZRC20AndCallZContractFailsIfSenderIsNotFungibleModule is correctly implemented with appropriate checks and event emissions.


385-395: LGTM!

The function testDepositZRC20AndCallZContractIfTargetIsFungibleModule is correctly implemented with appropriate checks and event emissions.


398-409: LGTM!

The function testDepositZRC20AndCallZContractIfTargetIsGateway is correctly implemented with appropriate checks and event emissions.


411-429: LGTM!

The function testDepositAndRevertZRC20AndCallZContract is correctly implemented with appropriate checks and event emissions.


431-442: LGTM!

The function testDepositAndRevertZRC20AndCallZContractFailsIfSenderIsNotFungibleModule is correctly implemented with appropriate checks and event emissions.


444-455: LGTM!

The function testDepositAndRevertZRC20AndCallZContractFailsITargetIsFungibleModule is correctly implemented with appropriate checks and event emissions.

Comment on lines 30 to 35
function receiveERC20Partial(uint256 amount, address token, address destination) external {
// Transfer half the tokens from the Gateway contract to the destination address
IERC20(token).safeTransferFrom(msg.sender, destination, amount / 2);

emit ReceivedERC20(msg.sender, amount / 2, token, destination);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix reentrancy vulnerability.

The function receiveERC20Partial introduces a reentrancy vulnerability by emitting an event after an external call. Use the Checks-Effects-Interactions pattern to mitigate this issue.

-        IERC20(token).safeTransferFrom(msg.sender, destination, amount / 2);
+        uint256 halfAmount = amount / 2;
+        emit ReceivedERC20(msg.sender, halfAmount, token, destination);
+        IERC20(token).safeTransferFrom(msg.sender, destination, halfAmount);
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function receiveERC20Partial(uint256 amount, address token, address destination) external {
// Transfer half the tokens from the Gateway contract to the destination address
IERC20(token).safeTransferFrom(msg.sender, destination, amount / 2);
emit ReceivedERC20(msg.sender, amount / 2, token, destination);
}
function receiveERC20Partial(uint256 amount, address token, address destination) external {
// Transfer half the tokens from the Gateway contract to the destination address
uint256 halfAmount = amount / 2;
emit ReceivedERC20(msg.sender, halfAmount, token, destination);
IERC20(token).safeTransferFrom(msg.sender, destination, halfAmount);
}
Tools
GitHub Check: Slither

[notice] 30-35: Reentrancy vulnerabilities
Reentrancy in ReceiverEVM.receiveERC20Partial(uint256,address,address) (contracts/prototypes/evm/ReceiverEVM.sol#30-35):
External calls:
- IERC20(token).safeTransferFrom(msg.sender,destination,amount / 2) (contracts/prototypes/evm/ReceiverEVM.sol#32)
Event emitted after the call(s):
- ReceivedERC20(msg.sender,amount / 2,token,destination) (contracts/prototypes/evm/ReceiverEVM.sol#34)

@lumtis
Copy link
Member

lumtis commented Jul 23, 2024

@coderabbitai can you review specifically the tests for contracts in prototypes and suggest if some edge cases are missing for the tests?

Copy link
Member

@lumtis lumtis left a comment

Choose a reason for hiding this comment

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

The tests look complete to me

Copy link
Contributor

coderabbitai bot commented Jul 23, 2024

Tip

For best results, initiate chat on the files or code changes.

Unable to process this comment: maximum number of iterations reached.

Analysis chain
#!/bin/bash
# Locate test files related to contracts in the prototypes directory
fd -e sol -e ts -e js -e tsx -e jsx -e json -e yaml -e yml -e md -e txt -e sh -e bash -e zsh -e fish -e ksh -e csh -e tcsh -e ps1 -e bat -e cmd -e vbs -e vb -e vba -e vbe -e wsf -e wsh -e scpt -e scptd -e applescript -e py -e pyc -e pyo -e pyd -e pyi -e pyw -e pyz -e pyzw -e pyx -e pxd -e pxi -e py3 -e py3x -e py3c -e py3d -e py3i -e py3w -e py3z -e py3zw -e py3xw -e py3xd -e py3xi -e py3p -e py3pzw -e py3px -e py3pxw -e py3pxd -e py3pxi -e py3pzp -e py3pzpzw -e py3pzx -e py3pzxw -e py3pzxd -e py3pzxi -e py3pzpz -e py3pzpzw -e py3pzpzx -e py3pzpzxw -e py3pzpzxd -e py3pzpzxi -e py3pzpzp -e py3pzpzpzw -e py3pzpzpzx -e py3pzpzpzxw -e py3pzpzpzxd -e py3pzpzpzxi -e py3pzpzpzp -e py3pzpzpzpzw -e py3pzpzpzpzx -e py3pzpzpzpzxw -e py3pzpzpzpzxd -e py3pzpzpzpzxi -e py3pzpzpzpzp -e py3pzpzpzpzpzw -e py3pzpzpzpzpzx -e py3pzpzpzpzpzxw -e py3pzpzpzpzpzxd -e py3pzpzpzpzpzxi -e py3pzpzpzpzpzp -e py3pzpzpzpzpzpzw -e py3pzpzpzpzpzpzx -e py3pzpzpzpzpzpzxw -e py3pzpzpzpzpzpzxd -e py3pzpzpzpzpzpzxi -e py3pzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp

---

<!-- [monologue]
[task 2/2] The script is designed to locate test files related to contracts in the `prototypes` directory. Once these files are identified, I will review their contents to determine if any edge cases are missing.
[observations] The test files are essential for verifying the functionality and robustness of the contracts. By reviewing these files, I can identify potential gaps in the test coverage.
[analysis] The next step is to run the script to gather the necessary information about the test files.
[actions] Execute the script to locate the test files and review their contents.
-->

```shell
#!/bin/bash
# Locate test files related to contracts in the prototypes directory
fd -e sol -e ts -e js -e tsx -e jsx -e json -e yaml -e yml -e md -e txt -e sh -e bash -e zsh -e fish -e ksh -e csh -e tcsh -e ps1 -e bat -e cmd -e vbs -e vb -e vba -e vbe -e wsf -e wsh -e scpt -e scptd -e applescript -e py -e pyc -e pyo -e pyd -e pyi -e pyw -e pyz -e pyzw -e pyx -e pxd -e pxi -e py3 -e py3x -e py3c -e py3d -e py3i -e py3w -e py3z -e py3zw -e py3xw -e py3xd -e py3xi -e py3p -e py3pzw -e py3px -e py3pxw -e py3pxd -e py3pxi -e py3pzp -e py3pzpzw -e py3pzx -e py3pzxw -e py3pzxd -e py3pzxi -e py3pzpz -e py3pzpzw -e py3pzpzx -e py3pzpzxw -e py3pzpzxd -e py3pzpzxi -e py3pzpzp -e py3pzpzpzw -e py3pzpzpzx -e py3pzpzpzxw -e py3pzpzpzxd -e py3pzpzpzxi -e py3pzpzpzp -e py3pzpzpzpzw -e py3pzpzpzpzx -e py3pzpzpzpzxw -e py3pzpzpzpzxd -e py3pzpzpzpzxi -e py3pzpzpzpzp -e py3pzpzpzpzpzw -e py3pzpzpzpzpzx -e py3pzpzpzpzpzxw -e py3pzpzpzpzpzxd -e py3pzpzpzpzpzxi -e py3pzpzpzpzpzp -e py3pzpzpzpzpzpzw -e py3pzpzpzpzpzpzx -e py3pzpzpzpzpzpzxw -e py3pzpzpzpzpzpzxd -e py3pzpzpzpzpzpzxi -e py3pzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzp

---

<!-- [monologue]
[task 2/2] The script has been executed to locate the test files related to contracts in the `prototypes` directory. The next step is to review these test files to identify any missing edge cases.
[observations] The identified test files will provide insights into the current test coverage and help determine if any edge cases are missing.
[analysis] Review the contents of the test files to identify potential gaps in the test coverage.
[actions] Analyze the test files and provide feedback on any missing edge cases.
-->

```shell
#!/bin/bash
# Locate test files related to contracts in the prototypes directory
fd -e sol -e ts -e js -e tsx -e jsx -e json -e yaml -e yml -e md -e txt -e sh -e bash -e zsh -e fish -e ksh -e csh -e tcsh -e ps1 -e bat -e cmd -e vbs -e vb -e vba -e vbe -e wsf -e wsh -e scpt -e scptd -e applescript -e py -e pyc -e pyo -e pyd -e pyi -e pyw -e pyz -e pyzw -e pyx -e pxd -e pxi -e py3 -e py3x -e py3c -e py3d -e py3i -e py3w -e py3z -e py3zw -e py3xw -e py3xd -e py3xi -e py3p -e py3pzw -e py3px -e py3pxw -e py3pxd -e py3pxi -e py3pzp -e py3pzpzw -e py3pzx -e py3pzxw -e py3pzxd -e py3pzxi -e py3pzpz -e py3pzpzw -e py3pzpzx -e py3pzpzxw -e py3pzpzxd -e py3pzpzxi -e py3pzpzp -e py3pzpzpzw -e py3pzpzpzx -e py3pzpzpzxw -e py3pzpzpzxd -e py3pzpzpzxi -e py3pzpzpzp -e py3pzpzpzpzw -e py3pzpzpzpzx -e py3pzpzpzpzxw -e py3pzpzpzpzxd -e py3pzpzpzpzxi -e py3pzpzpzpzp -e py3pzpzpzpzpzw -e py3pzpzpzpzpzx -e py3pzpzpzpzpzxw -e py3pzpzpzpzpzxd -e py3pzpzpzpzpzxi -e py3pzpzpzpzpzp -e py3pzpzpzpzpzpzw -e py3pzpzpzpzpzpzx -e py3pzpzpzpzpzpzxw -e py3pzpzpzpzpzpzxd -e py3pzpzpzpzpzpzxi -e py3pzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzpzp

---

<!-- [monologue]
[task 2/2] The script has been executed to locate the test files related to contracts in the `prototypes` directory. The next step is to review these test files to identify any missing edge cases.
[observations] The identified test files will provide insights into the current test coverage and help determine if any edge cases are missing.
[analysis] Review the contents of the test files to identify potential gaps in the test coverage.
[actions] Analyze the test files and provide feedback on any missing edge cases.
-->

```shell
#!/bin/bash
# Locate test files related to contracts in the prototypes directory
fd -e sol -e ts -e js -e tsx -e jsx -e json -e yaml -e yml -e md -e txt -e sh -e bash -e zsh -e fish -e ksh -e csh -e tcsh -e ps1 -e bat -e cmd -e vbs -e vb -e vba -e vbe -e wsf -e wsh -e scpt -e scptd -e applescript -e py -e pyc -e pyo -e pyd -e pyi -e pyw -e pyz -e pyzw -e pyx -e pxd -e pxi -e py3 -e py3x -e py3c -e py3d -e py3i -e py3w -e py3z -e py3zw -e py3xw -e py3xd -e py3xi -e py3p -e py3pzw -e py3px -e py3pxw -e py3pxd -e py3pxi -e py3pzp -e py3pzpzw -e py3pzx -e py3pzxw -e py3pzxd -e py3pzxi -e py3pzpz -e py3pzpzw -e py3pzpzx -e py3pzpzxw -e py3pzpzxd -e py3pzpzxi -e py3pzpzp -e py3pzpzpzw -e py3pzpzpzx -e py3pzpzpzxw -e py3pzpzpzxd -e py3pzpzpzxi -e py3pzpzpzp -e py3pzpzpzpzw -e py3pzpzpzpzx -e py3pzpzpzpzxw -e py3pzpzpzpzxd -e py3pzpzpzpzxi -e py3pzpzpzpzp -e py3pzpzpzpzpzw -e py3pzpzpzpzpzx -e py3pzpzpzpzpzxw -e py3pzpzpzpzpzxd -e py3pzpzpzpzpzxi -e py3pzpzpzpzpzp -e py3pzpzpzpzpzpzw -e py3pzpzpzpzpzpzx -e py3pzpzpzpzpzpzxw -e py3pzpzpzpzpzpzxd -e py3pzpzpzpzpzpzxi -e py3pzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzp

---

<!-- [monologue]
[task 2/2] The script has been executed to locate the test files related to contracts in the `prototypes` directory. The next step is to review these test files to identify any missing edge cases.
[observations] The identified test files will provide insights into the current test coverage and help determine if any edge cases are missing.
[analysis] Review the contents of the test files to identify potential gaps in the test coverage.
[actions] Analyze the test files and provide feedback on any missing edge cases.
-->

```shell
#!/bin/bash
# Locate test files related to contracts in the prototypes directory
fd -e sol -e ts -e js -e tsx -e jsx -e json -e yaml -e yml -e md -e txt -e sh -e bash -e zsh -e fish -e ksh -e csh -e tcsh -e ps1 -e bat -e cmd -e vbs -e vb -e vba -e vbe -e wsf -e wsh -e scpt -e scptd -e applescript -e py -e pyc -e pyo -e pyd -e pyi -e pyw -e pyz -e pyzw -e pyx -e pxd -e pxi -e py3 -e py3x -e py3c -e py3d -e py3i -e py3w -e py3z -e py3zw -e py3xw -e py3xd -e py3xi -e py3p -e py3pzw -e py3px -e py3pxw -e py3pxd -e py3pxi -e py3pzp -e py3pzpzw -e py3pzx -e py3pzxw -e py3pzxd -e py3pzxi -e py3pzpz -e py3pzpzw -e py3pzpzx -e py3pzpzxw -e py3pzpzxd -e py3pzpzxi -e py3pzpzp -e py3pzpzpzw -e py3pzpzpzx -e py3pzpzpzxw -e py3pzpzpzxd -e py3pzpzpzxi -e py3pzpzpzp -e py3pzpzpzpzw -e py3pzpzpzpzx -e py3pzpzpzpzxw -e py3pzpzpzpzxd -e py3pzpzpzpzxi -e py3pzpzpzpzp -e py3pzpzpzpzpzw -e py3pzpzpzpzpzx -e py3pzpzpzpzpzxw -e py3pzpzpzpzpzxd -e py3pzpzpzpzpzxi -e py3pzpzpzpzpzp -e py3pzpzpzpzpzpzw -e py3pzpzpzpzpzpzx -e py3pzpzpzpzpzpzxw -e py3pzpzpzpzpzpzxd -e py3pzpzpzpzpzpzxi -e py3pzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzx -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzpzxw -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxd -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzxi -e py3pzpzpzpzpzpzpzpzpzpzpzpzpzp -e py3pzpzpzpzp

</details>

<details>
<summary>Scripts executed</summary>

The following scripts were executed for the analysis:



---



---



---



---



</details>

@skosito skosito requested a review from fbac July 23, 2024 14:00
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9a299da and d2826bf.

Files ignored due to path filters (12)
  • pkg/contracts/prototypes/evm/receiverevm.sol/receiverevm.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/testerc20.sol/testerc20.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/zetaconnectornative.sol/zetaconnectornative.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/zetaconnectornonnative.sol/zetaconnectornonnative.go is excluded by !pkg/**
  • pkg/contracts/prototypes/zevm/senderzevm.sol/senderzevm.go is excluded by !pkg/**
  • pkg/contracts/prototypes/zevm/testzcontract.sol/testzcontract.go is excluded by !pkg/**
  • typechain-types/factories/contracts/prototypes/evm/ReceiverEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/TestERC20__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/ZetaConnectorNative__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/ZetaConnectorNonNative__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/zevm/SenderZEVM__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/zevm/TestZContract__factory.ts is excluded by !typechain-types/**
Files selected for processing (6)
  • contracts/prototypes/evm/ReceiverEVM.sol (2 hunks)
  • contracts/prototypes/evm/TestERC20.sol (1 hunks)
  • contracts/prototypes/evm/ZetaConnectorNative.sol (2 hunks)
  • contracts/prototypes/evm/ZetaConnectorNonNative.sol (2 hunks)
  • contracts/prototypes/zevm/SenderZEVM.sol (1 hunks)
  • contracts/prototypes/zevm/TestZContract.sol (2 hunks)
Files skipped from review due to trivial changes (2)
  • contracts/prototypes/evm/TestERC20.sol
  • contracts/prototypes/zevm/SenderZEVM.sol
Files skipped from review as they are similar to previous changes (3)
  • contracts/prototypes/evm/ZetaConnectorNative.sol
  • contracts/prototypes/evm/ZetaConnectorNonNative.sol
  • contracts/prototypes/zevm/TestZContract.sol
Additional context used
Path-based instructions (1)
contracts/prototypes/evm/ReceiverEVM.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

GitHub Check: Slither
contracts/prototypes/evm/ReceiverEVM.sol

[notice] 32-39: Reentrancy vulnerabilities
Reentrancy in ReceiverEVM.receiveERC20Partial(uint256,address,address) (contracts/prototypes/evm/ReceiverEVM.sol#32-39):
External calls:
- IERC20(token).safeTransferFrom(msg.sender,destination,amountToSend) (contracts/prototypes/evm/ReceiverEVM.sol#36)
Event emitted after the call(s):
- ReceivedERC20(msg.sender,amountToSend,token,destination) (contracts/prototypes/evm/ReceiverEVM.sol#38)

Additional comments not posted (5)
contracts/prototypes/evm/ReceiverEVM.sol (5)

Line range hint 13-16:
LGTM!

The function receivePayable is correctly implemented.


Line range hint 18-21:
LGTM!

The function receiveNonPayable is correctly implemented.


Line range hint 23-28:
LGTM!

The function receiveERC20 is correctly implemented.

Tools
GitHub Check: Slither

[notice] 32-39: Reentrancy vulnerabilities
Reentrancy in ReceiverEVM.receiveERC20Partial(uint256,address,address) (contracts/prototypes/evm/ReceiverEVM.sol#32-39):
External calls:
- IERC20(token).safeTransferFrom(msg.sender,destination,amountToSend) (contracts/prototypes/evm/ReceiverEVM.sol#36)
Event emitted after the call(s):
- ReceivedERC20(msg.sender,amountToSend,token,destination) (contracts/prototypes/evm/ReceiverEVM.sol#38)


40-42: LGTM!

The function receiveNoParams is correctly implemented.


47-49: LGTM!

The function onRevert is correctly implemented.

contracts/prototypes/evm/ReceiverEVM.sol Outdated Show resolved Hide resolved
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: 1

Outside diff range, codebase verification and nitpick comments (1)
contracts/prototypes/evm/ReceiverEVM.sol (1)

9-10: Clarify the purpose of the contract.

The comment indicates that the contract is for testing. This is acceptable, but ensure that this contract is not used in production.

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d2826bf and b3485b9.

Files ignored due to path filters (2)
  • pkg/contracts/prototypes/evm/receiverevm.sol/receiverevm.go is excluded by !pkg/**
  • typechain-types/factories/contracts/prototypes/evm/ReceiverEVM__factory.ts is excluded by !typechain-types/**
Files selected for processing (1)
  • contracts/prototypes/evm/ReceiverEVM.sol (2 hunks)
Additional context used
Path-based instructions (1)
contracts/prototypes/evm/ReceiverEVM.sol (1)

Pattern contracts/**: Review the Solidity contracts for security vulnerabilities and best practices.

Additional comments not posted (6)
contracts/prototypes/evm/ReceiverEVM.sol (6)

6-7: Ensure necessary imports.

The import of ReentrancyGuard is appropriate for preventing reentrancy attacks. Ensure that all imported modules are necessary and used correctly.


13-15: LGTM!

The function handles payable transactions correctly and emits the event as expected.


Line range hint 17-19:
LGTM!

The function handles non-payable transactions correctly and emits the event as expected.


25-30: LGTM!

The function handles ERC20 token transfers correctly and emits the event as expected.


35-35: Check for zero amount.

The check for zero amount is appropriate. Ensure that this check is consistently applied across similar functions.


48-50: LGTM!

The function handles revert scenarios correctly and emits the event as expected.

contracts/prototypes/evm/ReceiverEVM.sol Show resolved Hide resolved
@skosito skosito merged commit a2da596 into main Jul 23, 2024
11 checks passed
@skosito skosito deleted the connector-and-revert-unit-tests branch July 23, 2024 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add foundry unit tests for connector and revert specs
4 participants