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

fix(contracts-rfq): add bridge/relay revert tests [SLT-322] #3251

Merged
merged 3 commits into from
Oct 9, 2024

Conversation

ChiTimesChi
Copy link
Collaborator

@ChiTimesChi ChiTimesChi commented Oct 8, 2024

Description
All of the following must end up in a revert to avoid stuck funds in the contract:

  • Not approving the necessary amount of ERC20 for bridging (this was already passing)
  • Supplying non-zero msg.value for bridging/relaying an ERC20 (this wasn't passing in e40195d and got fixed in e5a852f)

Summary by CodeRabbit

  • New Features

    • Improved error handling in the token transfer process to prevent unintended behavior with ETH and ERC20 tokens.
    • Enhanced testing coverage for the bridging functionality, including new test cases for token approval scenarios and message value conditions.
  • Bug Fixes

    • Implemented checks to ensure the bridge function behaves correctly under specific conditions, preventing errors related to token approvals and message values.

Copy link
Contributor

coderabbitai bot commented Oct 8, 2024

Walkthrough

The changes in this pull request primarily focus on the FastBridgeV2 contract, specifically the _pullToken function and its token transfer handling. Key modifications include enhanced error handling for non-zero message values, adjustments to balance recording logic, and clarifications in transfer conditions. Additionally, the testing framework for the FastBridgeV2SrcTest and FastBridgeV2DstTest contracts has been expanded with new test cases that validate the bridge function's behavior under various conditions, ensuring comprehensive coverage for potential edge cases.

Changes

File Change Summary
packages/contracts-rfq/contracts/FastBridgeV2.sol - Added error handling in _pullToken for non-zero msg.value.
- Adjusted balance recording logic to occur after the new check.
- Clarified transfer logic conditions for ERC20 tokens and ETH.
packages/contracts-rfq/test/FastBridgeV2.Src.t.sol - Added three new test functions to FastBridgeV2SrcTest for validating bridge function behavior under specific conditions.
- Retained existing test functions while enhancing coverage for revert conditions.
packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol - Added five new test functions to FastBridgeV2DstTest for validating relay transaction behavior under various conditions related to token approvals and message values.

Possibly related PRs

Suggested labels

needs-go-generate-services/rfq

Suggested reviewers

  • trajan0x
  • parodime

🐰 In the meadow, changes bloom,
With tokens dancing, dispelling gloom.
Error checks in place, oh what a sight,
Balances recorded, all feels right!
Tests are added, edge cases found,
In the world of bridges, joy abounds! 🌼


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between e40195d and e5a852f.

📒 Files selected for processing (1)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol

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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 using 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.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

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.

Copy link

cloudflare-workers-and-pages bot commented Oct 8, 2024

Deploying sanguine-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: e5a852f
Status: ✅  Deploy successful!
Preview URL: https://19c9ad8d.sanguine-fe.pages.dev
Branch Preview URL: https://fix-fbv2-user-bridge-revert.sanguine-fe.pages.dev

View logs

Copy link

codecov bot commented Oct 8, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 91.08833%. Comparing base (4b49879) to head (e5a852f).
Report is 11 commits behind head on master.

Additional details and impacted files
@@                 Coverage Diff                 @@
##              master       #3251         +/-   ##
===================================================
+ Coverage   91.00237%   91.08833%   +0.08596%     
===================================================
  Files             60          60                 
  Lines           1267        1268          +1     
  Branches         154         155          +1     
===================================================
+ Hits            1153        1155          +2     
+ Misses           111         110          -1     
  Partials           3           3                 
Flag Coverage Δ
packages 90.43902% <ø> (ø)
solidity 93.82716% <100.00000%> (+0.43873%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

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

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

🧹 Outside diff range and nitpick comments (2)
packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (2)

187-192: LGTM: Good test for insufficient token approval.

This test function verifies that the bridge operation reverts when the token approval is less than the required amount. It's an important check to ensure that the contract handles insufficient approvals correctly.

Consider adding an assertion to verify that the approval amount is actually set to the intended value before attempting the bridge operation. This would make the test more robust:

 function test_bridge_token_revert_approvedNotEnough() public {
     vm.prank(userA);
-    srcToken.approve(address(fastBridge), tokenParams.originAmount - 1);
+    uint256 approvalAmount = tokenParams.originAmount - 1;
+    srcToken.approve(address(fastBridge), approvalAmount);
+    assertEq(srcToken.allowance(userA, address(fastBridge)), approvalAmount, "Approval not set correctly");
     vm.expectRevert();
     bridge({caller: userA, msgValue: 0, params: tokenParams});
 }

194-197: LGTM: Good test for non-zero msg.value in token bridging.

This test function verifies that the bridge operation reverts when attempting to bridge tokens with a non-zero msg.value. It's a critical check to ensure that the contract prevents accidental ETH transfers during token bridging.

To improve clarity, consider adding a comment explaining why this scenario should revert and asserting that the contract's ETH balance remains unchanged:

 function test_bridge_token_revert_nonZeroMsgValue() public {
+    // Bridging tokens should not accept ETH, so this should revert
+    uint256 initialBalance = address(fastBridge).balance;
     vm.expectRevert();
     bridge({caller: userA, msgValue: tokenParams.originAmount, params: tokenParams});
+    assertEq(address(fastBridge).balance, initialBalance, "Contract balance should not change");
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 4b49879 and 8fd76b1.

📒 Files selected for processing (2)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol (1 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (1 hunks)
🧰 Additional context used
🔇 Additional comments (2)
packages/contracts-rfq/contracts/FastBridgeV2.sol (1)

345-347: Excellent security improvement and alignment with PR objectives.

The changes in the _pullToken function significantly enhance the contract's security and align perfectly with the PR objectives:

  1. The new check if (msg.value != 0) revert MsgValueIncorrect(); prevents unintended behavior when bridging ERC20 tokens, addressing the PR's second key condition.
  2. Moving the balance recording after this check improves efficiency by ensuring the balance is only recorded when necessary.

These modifications effectively prevent potential fund loss scenarios and improve the overall robustness of the bridging process.

packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (1)

180-185: LGTM: Good test case for zero token approval.

This test function correctly verifies that the bridge operation reverts when the token approval is set to zero. It's a crucial check to ensure that the contract handles insufficient approvals properly.

@ChiTimesChi ChiTimesChi force-pushed the fix/FbV2-user-bridge-revert-tests branch from 8fd76b1 to e40195d Compare October 9, 2024 12:10
@ChiTimesChi ChiTimesChi changed the title fix(contracts-rfq): add user bridge revert tests [SLT-322] fix(contracts-rfq): add bridge/relay revert tests [SLT-322] Oct 9, 2024
@github-actions github-actions bot added size/s and removed size/xs labels Oct 9, 2024
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: 0

🧹 Outside diff range and nitpick comments (3)
packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol (3)

364-369: Consider specifying the expected revert reason.

The test correctly checks for a revert when the relayer has approved zero tokens. However, to make the test more robust and informative, consider specifying the exact revert reason you expect.

You could modify the test as follows:

-        vm.expectRevert();
+        vm.expectRevert("ERC20: insufficient allowance");
         relay({caller: relayerA, msgValue: 0, bridgeTx: tokenTx});

This change will make the test more precise and easier to debug if it fails.


371-376: Enhance test precision by specifying the expected revert reason.

The test correctly checks for a revert when the relayer has approved insufficient tokens. To improve the test's robustness and clarity, consider specifying the exact revert reason you expect.

You could modify the test as follows:

-        vm.expectRevert();
+        vm.expectRevert("ERC20: insufficient allowance");
         relay({caller: relayerA, msgValue: 0, bridgeTx: tokenTx});

This change will make the test more precise and easier to debug if it fails.


364-396: Overall assessment of new test functions

The new test functions significantly enhance the test coverage for the FastBridgeV2 contract, particularly for edge cases and error conditions in token approvals and ETH transfers. These tests are crucial for ensuring the contract's robustness and security.

Key observations:

  1. All tests correctly use vm.expectRevert() to check for reverts in various scenarios.
  2. The tests cover important cases such as zero/insufficient token approvals and incorrect ETH values.

Recommendations for improvement:

  1. Specify exact revert reasons in all vm.expectRevert() calls for more precise testing.
  2. Verify that the contract actually implements the checks being tested, especially for ETH transfer edge cases.
  3. Consider adding assertions to check the state after failed transactions, ensuring no unintended side effects.

These tests significantly contribute to the contract's security. To further enhance the testing strategy, consider:

  1. Implementing property-based testing for a wider range of input values.
  2. Adding fuzzing tests to discover edge cases that might have been overlooked.
  3. Conducting integration tests that simulate real-world scenarios involving multiple contract interactions.
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8fd76b1 and e40195d.

📒 Files selected for processing (1)
  • packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol (4)

388-391: Enhance test precision and verify contract behavior for excess ETH.

The test checks for a revert when the message value is higher than required for an ETH relay. To improve the test and ensure it aligns with the contract's behavior:

  1. Specify the exact revert reason you expect, if applicable.
  2. Verify that the contract actually checks for and reverts on excess message value for ETH transfers.

Consider modifying the test as follows:

-        vm.expectRevert();
+        vm.expectRevert("FastBridgeV2: excess msg.value");
         relay({caller: relayerA, msgValue: ethParams.destAmount + 1, bridgeTx: ethTx});

To verify the contract's behavior, run the following script:

#!/bin/bash
# Description: Verify that FastBridgeV2 checks for excess msg.value in ETH transfers
ast-grep --lang solidity --pattern $'function _pullToken(address token, address from, uint256 amount) internal {
  $$$
  if (msg.value > amount) {
    revert("FastBridgeV2: excess msg.value");
  }
  $$$
}'

If the contract doesn't implement this check, consider whether this test is necessary or if the contract should be updated to include this check for better security.


383-386: Improve test precision and verify contract behavior for ETH transfers.

The test correctly checks for a revert when the message value is less than required for an ETH relay. To enhance the test's robustness and clarity:

  1. Consider specifying the exact revert reason you expect.
  2. Verify that the contract actually checks for and reverts on insufficient message value for ETH transfers.

You could modify the test as follows:

-        vm.expectRevert();
+        vm.expectRevert("FastBridgeV2: insufficient msg.value");
         relay({caller: relayerA, msgValue: ethParams.destAmount - 1, bridgeTx: ethTx});

To verify the contract's behavior, run the following script:

#!/bin/bash
# Description: Verify that FastBridgeV2 checks for insufficient msg.value in ETH transfers
ast-grep --lang solidity --pattern $'function _pullToken(address token, address from, uint256 amount) internal {
  $$$
  if (msg.value < amount) {
    revert("FastBridgeV2: insufficient msg.value");
  }
  $$$
}'

This change and verification will ensure that the test accurately reflects the contract's intended behavior for ETH transfers.


393-396: Improve test precision and verify contract behavior for zero ETH value.

The test checks for a revert when zero message value is provided for an ETH relay. To enhance the test's effectiveness:

  1. Specify the exact revert reason you expect.
  2. Verify that the contract actually checks for and reverts on zero message value for ETH transfers.

Consider modifying the test as follows:

-        vm.expectRevert();
+        vm.expectRevert("FastBridgeV2: zero msg.value for ETH transfer");
         relay({caller: relayerA, msgValue: 0, bridgeTx: ethTx});

To verify the contract's behavior, run the following script:

#!/bin/bash
# Description: Verify that FastBridgeV2 checks for zero msg.value in ETH transfers
ast-grep --lang solidity --pattern $'function _pullToken(address token, address from, uint256 amount) internal {
  $$$
  if (msg.value == 0) {
    revert("FastBridgeV2: zero msg.value for ETH transfer");
  }
  $$$
}'

This change and verification will ensure that the test accurately reflects the contract's intended behavior for ETH transfers with zero value.


378-381: Enhance test precision and verify contract behavior.

The test correctly checks for a revert when a non-zero message value is provided for an ERC20 token relay. To improve the test's robustness and clarity:

  1. Consider specifying the exact revert reason you expect.
  2. Verify that the contract actually checks for and reverts on non-zero message value for ERC20 tokens.

You could modify the test as follows:

-        vm.expectRevert();
+        vm.expectRevert("FastBridgeV2: non-zero msg.value for ERC20");
         relay({caller: relayerA, msgValue: tokenParams.destAmount, bridgeTx: tokenTx});

To verify the contract's behavior, run the following script:

This change and verification will ensure that the test accurately reflects the contract's intended behavior.

Copy link

github-actions bot commented Oct 9, 2024

Changes to gas cost

Generated at commit: bd630e0e56fded429b85e566b0017f962528a51d, compared to commit: 4b498794b45cc9b2e0e4ddb1bb60914381134558

🧾 Summary (50% most significant diffs)

Contract Method Avg (+/-) %
FastBridgeV2 bridge((uint32,address,address,address,address,uint256,uint256,bool,uint256),(address,int256,bytes,bytes))
relay(bytes)
relay(bytes,address)
+10 ❌
+10 ❌
+10 ❌
+0.01%
+0.01%
+0.01%

Full diff report 👇
Contract Deployment Cost (+/-) Method Min (+/-) % Avg (+/-) % Median (+/-) % Max (+/-) % # Calls (+/-)
FastBridgeV2 2,870,712 (+6,800) bridge((uint32,address,address,address,address,uint256,uint256,bool,uint256))
bridge((uint32,address,address,address,address,uint256,uint256,bool,uint256),(address,int256,bytes,bytes))
relay(bytes)
relay(bytes,address)
68,530 (0)
71,472 (0)
64,685 (0)
65,102 (0)
0.00%
0.00%
0.00%
0.00%
83,558 (+10)
82,347 (+10)
70,610 (+10)
71,027 (+10)
+0.01%
+0.01%
+0.01%
+0.01%
79,393 (+10)
82,347 (+10)
70,610 (+10)
71,027 (+10)
+0.01%
+0.01%
+0.01%
+0.01%
107,356 (+19)
93,222 (+19)
76,535 (+19)
76,952 (+19)
+0.02%
+0.02%
+0.02%
+0.02%
156 (0)
4 (0)
2 (0)
2 (0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant