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: initialize echidna for fuzz testing #208

Merged
merged 67 commits into from
Jul 11, 2024
Merged

test: initialize echidna for fuzz testing #208

merged 67 commits into from
Jul 11, 2024

Conversation

skosito
Copy link
Contributor

@skosito skosito commented Jul 4, 2024

to test:

Setup echidna

brew install echidna
solc-select use 0.8.7

Execute contract tests

echidna test/fuzz/ERC20CustodyNewEchidnaTest.sol --contract ERC20CustodyNewEchidnaTest  --config echidna.yaml
echidna test/fuzz/GatewayEVMEchidnaTest.sol --contract GatewayEVMEchidnaTest  --config echidna.yaml

just simple tests for now, and instructions on how to run, once we agree on approach we can open more issues for adding more fuzz tests same way its started here

alternatives:
foundry has built in fuzz testing, and bunch of tools for better testing in general (for example cheatcodes: https://book.getfoundry.sh/forge/cheatcodes)

Summary by CodeRabbit

  • New Features

    • Introduced echidna.yaml for crytic-compile configuration.
    • Added ERC20CustodyNewEchidnaTest.sol and GatewayEVMEchidnaTest.sol for advanced testing.
    • Added setup instructions for Echidna in readme.md.
  • Bug Fixes

    • Enhanced setCustody function in GatewayEVM.sol to prevent reinitialization.
  • Refactor

    • Changed withdrawAndCall function visibility from external to public in ERC20CustodyNew.
  • Chores

    • Updated .eslintignore and .gitignore to include crytic-export directory.

Copy link
Contributor

coderabbitai bot commented Jul 4, 2024

Walkthrough

This update primarily enhances testing and code management. It introduces .eslintignore and .gitignore updates for ignoring the crytic-export directory, changes function visibility in ERC20CustodyNew and GatewayEVM contracts, adds a new error type, and includes reinitialization checks. Additionally, it provides configurations for Echidna testing and integrates new test files for fuzz testing mechanisms.

Changes

Files/Paths Change Summary
.eslintignore, .gitignore Added crytic-export to ignore list, preserving other existing entries.
contracts/.../ERC20CustodyNew.sol Changed withdrawAndCall function visibility from external to public.
contracts/.../GatewayEVM.sol Added new error type CustodyInitialized and added reinitialization check in setCustody function.
echidna.yaml Introduced new file with configurations for crytic-compile.
test/fuzz/ERC20CustodyNewEchidnaTest.sol New file to extend ERC20CustodyNew for testing withdrawal and calling functionality.
test/fuzz/GatewayEVMEchidnaTest.sol New file to extend GatewayEVM for testing token execution with balance assertions.
test/fuzz/readme.md Added setup instructions for Echidna, including installation, Solidity version configuration, and running tests.

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant ERC20CustodyNew
    participant GatewayEVM
    Note right of Developer: Setup Echidna Testing
    Developer->>ERC20CustodyNew: Call withdrawAndCall as public
    Developer->>GatewayEVM: Deploy and setup initial custody
    GatewayEVM-->Developer: Error if custody already initialized
    Developer->>Echidna: Configure and run tests
    Echidna->>ERC20CustodyNew&GatewayEVM: Test fuzz cases
Loading

Poem

In fields of code where changes flow,
Functions now more public show,
Echidna tests run bright and fast,
Ensuring our contracts last.
Ignoring files both here and there,
Protects our repo, light as air.
With checks and balances now in place,
Our smart contracts bask in grace.
🐇✨


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 Configration 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.

@skosito
Copy link
Contributor Author

skosito commented Jul 4, 2024

@lumtis @fadeev @fbac could you please check this draft and let me know your thoughts, especially on points in PR description? thanks

@skosito
Copy link
Contributor Author

skosito commented Jul 4, 2024

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Jul 4, 2024

Actions performed

Full review triggered.

@codecov-commenter
Copy link

codecov-commenter commented Jul 4, 2024

Codecov Report

Attention: Patch coverage is 0% with 2 lines in your changes missing coverage. Please review.

Project coverage is 48.09%. Comparing base (b0fbc16) to head (4ec838c).

Files Patch % Lines
contracts/prototypes/evm/ERC20CustodyNew.sol 0.00% 1 Missing ⚠️
contracts/prototypes/evm/GatewayEVM.sol 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #208       +/-   ##
===========================================
- Coverage   59.25%   48.09%   -11.17%     
===========================================
  Files          31       31               
  Lines        1048     1048               
  Branches      262      263        +1     
===========================================
- Hits          621      504      -117     
- Misses        427      544      +117     

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

@skosito skosito linked an issue Jul 4, 2024 that may be closed by this pull request
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 41920d0 and 3190026.

Files ignored due to path filters (8)
  • pkg/contracts/prototypes/evm/erc20custodynew.sol/erc20custodynew.go is excluded by !pkg/**
  • pkg/contracts/prototypes/evm/gatewayevm.sol/gatewayevm.go is excluded by !pkg/**
  • typechain-types/contracts/prototypes/evm/ERC20CustodyNewEchidnaTest.ts is excluded by !typechain-types/**
  • typechain-types/contracts/prototypes/evm/GatewayEVMEchidnaTest.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/ERC20CustodyNewEchidnaTest__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/ERC20CustodyNew__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/GatewayEVMEchidnaTest__factory.ts is excluded by !typechain-types/**
  • typechain-types/factories/contracts/prototypes/evm/GatewayEVM__factory.ts is excluded by !typechain-types/**
Files selected for processing (8)
  • .eslintignore (1 hunks)
  • .gitignore (1 hunks)
  • contracts/prototypes/evm/ERC20CustodyNew.sol (1 hunks)
  • contracts/prototypes/evm/GatewayEVM.sol (4 hunks)
  • echidna.yaml (1 hunks)
  • test/fuzz/ERC20CustodyNewEchidnaTest.sol (1 hunks)
  • test/fuzz/GatewayEVMEchidnaTest.sol (1 hunks)
  • test/fuzz/readme.md (1 hunks)
Additional context used
Path-based instructions (5)
test/fuzz/readme.md (1)

Pattern test/**: Review the test files for proper coverage, edge cases, and best practices.

test/fuzz/GatewayEVMEchidnaTest.sol (1)

Pattern test/**: Review the test files for proper coverage, edge cases, and best practices.

test/fuzz/ERC20CustodyNewEchidnaTest.sol (1)

Pattern test/**: Review the test files for proper coverage, edge cases, and best practices.

contracts/prototypes/evm/ERC20CustodyNew.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.

yamllint
echidna.yaml

[error] 4-4: trailing spaces

(trailing-spaces)


[error] 5-5: trailing spaces

(trailing-spaces)


[error] 6-6: no new line character at the end of file

(new-line-at-end-of-file)

Markdownlint
test/fuzz/readme.md

3-3: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)


10-10: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)


13-13: null
Files should end with a single newline character

(MD047, single-trailing-newline)

Additional comments not posted (15)
.eslintignore (1)

7-8: LGTM!

The additions of docs and crytic-export directories to the ignore list are appropriate.

.gitignore (1)

33-35: LGTM!

The additions of abi and crytic-export directories to the ignore list are appropriate.

test/fuzz/GatewayEVMEchidnaTest.sol (5)

1-5: Imports look good.

The necessary modules and libraries are imported correctly.


7-8: Ensure proper usage of SafeERC20.

The SafeERC20 library is used, which is good for preventing common ERC20 pitfalls.


10-11: State variable initialization.

The state variables are initialized correctly. Ensure echidnaCaller is properly set during tests.


13-17: Constructor initialization logic.

The constructor initializes the contract correctly. Ensure that initialize and new calls are functioning as expected.


19-26: Test function for ERC20 execution.

The test function testExecuteWithERC20 is well-structured. Ensure that the minting and execution logic works as intended.

test/fuzz/ERC20CustodyNewEchidnaTest.sol (5)

1-5: Imports look good.

The necessary modules and libraries are imported correctly.


7-8: Ensure proper usage of SafeERC20.

The SafeERC20 library is used, which is good for preventing common ERC20 pitfalls.


10-11: State variable initialization.

The state variables are initialized correctly. Ensure echidnaCaller is properly set during tests.


13-19: Constructor initialization logic.

The constructor initializes the contract correctly. Ensure that initialize and setCustody calls are functioning as expected.


21-31: Test function for withdraw and call.

The test function testWithdrawAndCall is well-structured. Ensure that the minting, transferring, and withdrawal logic works as intended.

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

41-41: Visibility change of withdrawAndCall.

Changing the visibility from external to public allows the function to be called internally, which might be necessary for testing or other internal logic. Ensure that this change does not introduce any security vulnerabilities.

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

21-21: New error type CustodyInitialized.

The new error type CustodyInitialized is defined to handle reinitialization errors. Ensure that this error is used correctly in the contract.


138-138: Visibility change of setCustody.

Changing the visibility from external to public allows the function to be called internally, which might be necessary for testing or other internal logic. Ensure that this change does not introduce any security vulnerabilities.

Comment on lines +4 to +6
testLimit: 50000
seqLen: 10000
allContracts: false
Copy link
Contributor

Choose a reason for hiding this comment

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

Fix trailing spaces and add a newline at the end of the file.

There are trailing spaces on lines 4 and 5, and the file is missing a newline at the end.

- testLimit: 50000  
- seqLen: 10000 
+ testLimit: 50000
+ seqLen: 10000

+ 
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
testLimit: 50000
seqLen: 10000
allContracts: false
testLimit: 50000
seqLen: 10000
allContracts: false
Tools
yamllint

[error] 4-4: trailing spaces

(trailing-spaces)


[error] 5-5: trailing spaces

(trailing-spaces)


[error] 6-6: no new line character at the end of file

(new-line-at-end-of-file)

@@ -0,0 +1,13 @@
## Setup echidna

```
Copy link
Contributor

Choose a reason for hiding this comment

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

Specify language for fenced code blocks and add a newline at the end of the file.

Fenced code blocks should have a language specified, and the file should end with a newline.

- ```
+ ```sh

- ```
+ ```sh

+ 

Also applies to: 10-10, 13-13

Tools
Markdownlint

3-3: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)

@fadeev
Copy link
Member

fadeev commented Jul 5, 2024

I think using Foundry more is a good idea. What I still like about Hardhat is the ability to import and use TypeScript tools, we're using them for everything in tutorials: balances, faucet, transaction tracking, code generation. But I think Hardhat-Foundry plugin is a good middle-ground.

@@ -38,7 +38,7 @@ contract ERC20CustodyNew is ReentrancyGuard{
// For this, it passes through the Gateway contract, it transfers the tokens to the Gateway contract and then calls the contract
// TODO: Finalize access control
// https://github.com/zeta-chain/protocol-contracts/issues/204
function withdrawAndCall(address token, address to, uint256 amount, bytes calldata data) external nonReentrant {
function withdrawAndCall(address token, address to, uint256 amount, bytes calldata data) public nonReentrant {
Copy link
Contributor

Choose a reason for hiding this comment

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

Under which circumstances is withdrawAndCall and executeWithERC20 be called from within ERC20CustodyNew? This impacts the amount of gas consumed by these functions.

Copy link
Member

Choose a reason for hiding this comment

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

What do you mean by circumstances?
withdrawAndCall is called by the TSS address when handling an outbound

Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably will be clearer when we add access control

@fbac
Copy link
Contributor

fbac commented Jul 5, 2024

I don't have enough experience with Echidna yet to make a proper statement.
Regarding hardhat vs. foundry I'd say I prefer foundry because it allows native solidity testing, fuzzing and in general better it's a better testing suite than hh is. On the other hand, I get that it can be hard to fully migrate.

I agree with the proposed hardhat-foundry usage, it's a good middle ground and the full migration can happen if everyone agrees about foundry being the best solution.

Also, I'll be studying echidna so I can have informed opinions on it.

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.

Looks good to me.

We don't need to be complete in this PR, just write the base.

foundry instead of hardhat: too much effort atm to migrate

What concrete work to migrate outside of rewriting the test and deployment scripts?
Also myaybe we can have both supported atm?

@@ -38,7 +38,7 @@ contract ERC20CustodyNew is ReentrancyGuard{
// For this, it passes through the Gateway contract, it transfers the tokens to the Gateway contract and then calls the contract
// TODO: Finalize access control
// https://github.com/zeta-chain/protocol-contracts/issues/204
function withdrawAndCall(address token, address to, uint256 amount, bytes calldata data) external nonReentrant {
function withdrawAndCall(address token, address to, uint256 amount, bytes calldata data) public nonReentrant {
Copy link
Member

Choose a reason for hiding this comment

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

What do you mean by circumstances?
withdrawAndCall is called by the TSS address when handling an outbound

@skosito
Copy link
Contributor Author

skosito commented Jul 5, 2024

Looks good to me.

We don't need to be complete in this PR, just write the base.

foundry instead of hardhat: too much effort atm to migrate

What concrete work to migrate outside of rewriting the test and deployment scripts? Also myaybe we can have both supported atm?

i think tests and scripts, probably not that much effort if we only do it for v2
i will convert this PR to ready for review and try hadhat-foundry plugin in next PR (#210), so PRs are smaller and more focused, because even if we move to foundry having echidna setup might still be beneficial

@skosito skosito marked this pull request as ready for review July 5, 2024 13:34
@skosito skosito requested review from lumtis and fbac July 5, 2024 13:35
@lumtis
Copy link
Member

lumtis commented Jul 5, 2024

i think tests and scripts, probably not that much effort if we only do it for v2

We could also consider create entire new repo for v2 as the env is just completely different

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.

@skosito can we add instructions in the PR how it can be tested?

@skosito
Copy link
Contributor Author

skosito commented Jul 5, 2024

@skosito can we add instructions in the PR how it can be tested?

yes, i added a readme in tests/fuzz/readme.md, but also copied to PR description

@skosito skosito requested a review from lumtis July 9, 2024 01:37
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.

Tested the commands, looking good to me

@skosito
Copy link
Contributor Author

skosito commented Jul 10, 2024

Tested the commands, looking good to me

thank you, @fbac @fadeev could you please review as well, need 1 more review to close this one?

@skosito skosito merged commit 972ceb1 into main Jul 11, 2024
11 checks passed
@skosito skosito deleted the fuzz-tests-poc branch July 11, 2024 12:09
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.

Investigate fuzzing testing integration
5 participants