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

feat(contracts-rfq): add version to BridgeTransaction, tight packing [SLT-328] [SLT-273] #3284

Merged
merged 15 commits into from
Oct 18, 2024

Conversation

ChiTimesChi
Copy link
Collaborator

@ChiTimesChi ChiTimesChi commented Oct 14, 2024

Description

  • BridgeTransaction version is added into the encoded payload, allowing to do small changes for whatever is coming in BridgeTransactionV3.
  • BridgeTransaction struct is now tightly packed for the encoding. This makes the decoding a bit more efficient, as well as decreases the encoded transaction length. Both of these result in gas savings, making both relay and claim ~3k gas cheaper on average.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced the BridgeTransactionV2Lib library for efficient encoding and decoding of bridge transactions.
    • Added a new function getBridgeTransactionV2 for enhanced transaction retrieval.
    • Improved gas efficiency by optimizing function parameters and data handling.
    • New functions for creating and validating mock requests have been added.
  • Bug Fixes

    • Enhanced error handling for unsupported versions and invalid requests in transaction processes.
  • Tests

    • Updated and added tests to validate new functionalities and ensure robustness against invalid inputs.

Copy link
Contributor

coderabbitai bot commented Oct 14, 2024

Walkthrough

The pull request introduces significant updates to the FastBridgeV2 contract and related components to enhance gas efficiency and maintainability. Key modifications include changing function parameters from memory to calldata, utilizing the new BridgeTransactionV2Lib library for encoding and decoding bridge transaction data, and refactoring several functions for improved logic. Additionally, new tests have been added to validate the updated functionality and error handling, ensuring robustness in various scenarios.

Changes

File Path Change Summary
packages/contracts-rfq/contracts/FastBridgeV2.sol Updated function signatures to use calldata instead of memory, added getBridgeTransactionV2, refactored refund and claim functions, and updated _validateRelayParams for improved efficiency.
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Introduced BridgeTransactionV2Lib library for encoding and decoding transactions, added multiple functions for validation and data retrieval, and defined error types for handling invalid transactions.
packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol Updated to use BridgeTransactionV2Lib for encoding in relay functions.
packages/contracts-rfq/test/FastBridgeV2.Src.t.sol Integrated BridgeTransactionV2Lib for encoding bridge transactions, added new tests for invalid payload scenarios in prove, claim, and refund functions.
packages/contracts-rfq/test/FastBridgeV2.t.sol Updated to include new imports and functions for mock requests and error handling, utilizing BridgeTransactionV2Lib for generating transaction IDs.

Possibly related PRs

Suggested reviewers

  • ChiTimesChi
  • trajan0x
  • parodime

Poem

🐰 In the code where bridges flow,
Gas is saved, and logic's glow.
With libraries bright, we encode with glee,
Transactions dance, as smooth as can be.
So hop along, let changes ring,
For in the world of code, we’re the spring! 🌼


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 14, 2024

Deploying sanguine-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2c18409
Status: ✅  Deploy successful!
Preview URL: https://808011ee.sanguine-fe.pages.dev
Branch Preview URL: https://feat-fbv2-version-encoding.sanguine-fe.pages.dev

View logs

Copy link

github-actions bot commented Oct 14, 2024

Changes to gas cost

Generated at commit: a1d9902471558640fbf6b50245c75295be7fe4c1, compared to commit: a0684a80999f0494db02ab160432f87dce38c7e7

🧾 Summary (50% most significant diffs)

Contract Method Avg (+/-) %
FastBridgeV2 claim(bytes)
claim(bytes,address)
getBridgeTransaction
getBridgeTransactionV2
refund
relay(bytes)
-3,282 ✅
-3,290 ✅
-1,338 ✅
-708 ✅
-3,251 ✅
-3,104 ✅
-6.53%
-6.34%
-23.90%
-21.55%
-6.30%
-4.37%

Full diff report 👇
Contract Deployment Cost (+/-) Method Min (+/-) % Avg (+/-) % Median (+/-) % Max (+/-) % # Calls (+/-)
FastBridgeV2 3,199,470 (+200,058) bridge
claim(bytes)
claim(bytes,address)
dispute
getBridgeTransaction
getBridgeTransactionV2
prove(bytes,bytes32)
prove(bytes32,bytes32,address)
refund
relay(bytes)
relay(bytes,address)
68,979 (-1,627)
40,038 (-3,214)
42,901 (-3,222)
31,092 (-12)
4,260 (-1,338)
1,150 (-258)
34,632 (-862)
32,061 (+36)
44,402 (-3,197)
61,435 (-2,984)
61,844 (-2,992)
-2.30%
-7.43%
-6.99%
-0.04%
-23.90%
-18.32%
-2.43%
+0.11%
-6.72%
-4.63%
-4.61%
80,399 (-1,629)
46,949 (-3,282)
48,562 (-3,290)
31,100 (-4)
4,260 (-1,338)
2,577 (-708)
34,945 (-866)
32,069 (+9)
48,373 (-3,251)
67,874 (-3,104)
68,283 (-3,112)
-1.99%
-6.53%
-6.34%
-0.01%
-23.90%
-21.55%
-2.42%
+0.03%
-6.30%
-4.37%
-4.36%
81,038 (-1,628)
47,533 (-3,234)
49,146 (-3,242)
31,104 (0)
4,260 (-1,338)
3,214 (-863)
34,656 (-862)
32,073 (+12)
48,508 (-3,277)
67,808 (-3,160)
68,217 (-3,168)
-1.97%
-6.37%
-6.19%
0.00%
-23.90%
-21.17%
-2.43%
+0.04%
-6.33%
-4.45%
-4.44%
93,121 (-1,630)
54,992 (-3,255)
55,355 (-3,263)
31,104 (0)
4,260 (-1,338)
3,367 (-1,004)
35,596 (-874)
32,073 (+12)
52,614 (-3,357)
76,996 (-3,327)
77,405 (-3,335)
-1.72%
-5.59%
-5.57%
0.00%
-23.90%
-22.97%
-2.40%
+0.04%
-6.00%
-4.14%
-4.13%
260 (0)
6 (0)
6 (0)
6 (0)
1 (0)
3 (0)
68 (0)
68 (0)
12 (0)
6 (0)
6 (0)

Copy link

codecov bot commented Oct 14, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 28.69508%. Comparing base (a0684a8) to head (2c18409).
Report is 4 commits behind head on master.

❗ There is a different number of reports uploaded between BASE (a0684a8) and HEAD (2c18409). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (a0684a8) HEAD (2c18409)
solidity 3 2
Additional details and impacted files
@@                 Coverage Diff                 @@
##              master       #3284         +/-   ##
===================================================
- Coverage   34.42327%   28.69508%   -5.72820%     
===================================================
  Files            218         184         -34     
  Lines          13273       12131       -1142     
  Branches         356         161        -195     
===================================================
- Hits            4569        3481       -1088     
+ Misses          8414        8366         -48     
+ Partials         290         284          -6     
Flag Coverage Δ
packages 90.44834% <ø> (ø)
solidity 96.64430% <100.00000%> (+1.08874%) ⬆️

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.

packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol Dismissed Show dismissed Hide dismissed
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: 8

🧹 Outside diff range and nitpick comments (18)
packages/contracts-rfq/test/FastBridgeV2.GasBench.Encoding.t.sol (1)

16-16: LGTM: Encoding method updated to use BridgeTransactionV2Lib.

The change from abi.encode(tokenTx) to BridgeTransactionV2Lib.encodeV2(tokenTx) aligns with the PR objectives and likely improves gas efficiency. This update is appropriate for a V2 test.

Consider adding a comment explaining the gas efficiency improvement, e.g.:

// Use BridgeTransactionV2Lib.encodeV2 for improved gas efficiency
bytes memory request = BridgeTransactionV2Lib.encodeV2(tokenTx);
packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol (1)

Line range hint 1-51: Summary: Consistent implementation of new BridgeTransactionV2 encoding

The changes in this file consistently implement a new encoding method for BridgeTransactionV2 using BridgeTransactionV2Lib.encodeV2(). This appears to be part of a larger refactoring effort.

To ensure the integrity of this refactoring:

  1. Verify that all occurrences of BridgeTransactionV2 encoding throughout the codebase have been updated to use the new method.
  2. Ensure that corresponding decoding methods are implemented and tested.
  3. Update relevant documentation to reflect this change in encoding methodology.
  4. Consider adding integration tests to verify the compatibility of this encoding change with other components of the system.
packages/contracts-rfq/test/libs/BridgeTransactionV2.t.sol (4)

8-8: Consider addressing linter warnings instead of disabling them.

The solhint-disable comment is suppressing warnings for func-name-mixedcase and ordering. While this can be useful for temporary development, it's generally better to address these issues directly:

  1. For func-name-mixedcase: Consider renaming test functions to follow Solidity naming conventions (e.g., testRoundtrip instead of test_roundtrip).
  2. For ordering: Reorganize the contract members to follow the recommended order (type declarations, state variables, events, modifiers, constructors, functions).

Addressing these issues can improve code readability and maintainability.


16-38: LGTM: Comprehensive equality check for BridgeTransactionV2.

The assertEq function thoroughly compares all fields of the BridgeTransactionV2 struct, which is excellent for detailed testing. The use of individual assertEq calls for each field will provide more specific error messages if a test fails.

Consider adding a custom error message parameter to provide context when assertions fail:

function assertEq(
    IFastBridgeV2.BridgeTransactionV2 memory a,
    IFastBridgeV2.BridgeTransactionV2 memory b,
    string memory message
) public pure {
    assertEq(a.originChainId, b.originChainId, string(abi.encodePacked(message, ": originChainId mismatch")));
    // Repeat for other fields...
}

This would allow test cases to provide more context when calling this function, making debugging easier.


40-58: LGTM: Comprehensive roundtrip test for BridgeTransactionV2.

The test_roundtrip function thoroughly tests the encoding process by checking each field individually after encoding. This approach ensures that all data is correctly preserved during the encoding process.

To improve test coverage and readability, consider:

  1. Adding explicit test cases with predefined BridgeTransactionV2 structs to cover edge cases.
  2. Using a helper function to reduce repetition in assertions:
function assertEncodedTxEquals(bytes memory encodedTx, IFastBridgeV2.BridgeTransactionV2 memory expectedTx) internal view {
    assertEq(harness.version(encodedTx), 2);
    assertEq(harness.originChainId(encodedTx), expectedTx.originChainId);
    // ... repeat for other fields
}

function test_roundtrip(IFastBridgeV2.BridgeTransactionV2 memory bridgeTx) public view {
    bytes memory encodedTx = harness.encodeV2(bridgeTx);
    assertEncodedTxEquals(encodedTx, bridgeTx);
}

This refactoring would make the test more maintainable and easier to extend with additional test cases.


60-64: LGTM: Effective roundtrip test for encoding and decoding.

The test_roundtrip_decodeV2 function effectively tests both the encoding and decoding processes in a single roundtrip. The use of the custom assertEq function ensures a thorough comparison of all fields.

To enhance the test coverage, consider adding the following:

  1. Explicit test cases with predefined BridgeTransactionV2 structs to cover edge cases and specific scenarios.
  2. Negative tests to ensure proper handling of invalid encoded data:
function test_decodeV2_invalidData() public {
    bytes memory invalidEncodedTx = abi.encodePacked(bytes1(0x02), bytes31(0));
    vm.expectRevert("Invalid encoded transaction");
    harness.decodeV2(invalidEncodedTx);
}
  1. A test for backwards compatibility if there's a previous version of the encoding:
function test_decodeV2_backwardsCompatibility() public {
    // Assuming there's a V1 encoding function
    bytes memory v1EncodedTx = harness.encodeV1(/* ... */);
    vm.expectRevert("Unsupported version");
    harness.decodeV2(v1EncodedTx);
}

These additions would provide more comprehensive coverage of the encoding and decoding functionality.

packages/contracts-rfq/test/FastBridgeV2.Encoding.t.sol (3)

46-49: LGTM: Renamed parameter for clarity in test_getBridgeTransaction.

The renaming of bridgeTx to bridgeTxV1 improves the clarity of the test case, explicitly indicating that it's for V1 transactions. This change is consistent with the support for both V1 and V2 transactions.

Consider updating the function name to test_getBridgeTransactionV1 for even better clarity and consistency with the V2 test case naming.


56-60: LGTM: Updated encoding and expectation for V2 transactions.

The changes correctly implement the new encoding strategy for V2 transactions using BridgeTransactionV2Lib.encodeV2. The adjustment of sendChainGas based on callValue accurately reflects the changes in the V2 transaction structure.

Consider extracting the sendChainGas assignment to a separate line for improved readability:

expectedTx = extractV1(bridgeTxV2);
expectedTx.sendChainGas = bridgeTxV2.callValue > 0;
assertEq(decodedTx, expectedTx);

69-73: LGTM: Renamed parameter for clarity in test_getBridgeTransactionV2_revert_usedRequestV1.

The renaming of bridgeTx to bridgeTxV1 improves the clarity of the test case, explicitly indicating that it's using a V1 transaction to test the revert behavior of the V2 function.

For consistency with the other test cases, consider updating the encoding to use abi.encode explicitly:

bytes memory request = abi.encode(bridgeTxV1);

This change would make it clearer that we're using the V1 encoding method for this test case.

packages/contracts-rfq/test/harnesses/BridgeTransactionV2Harness.sol (2)

15-77: LGTM: All getter functions correctly wrap library methods.

All getter functions (version through callParams) are implemented correctly, providing a clean interface to their corresponding BridgeTransactionV2Lib methods. The consistent use of calldata for input parameters is gas-efficient.

Consider adding NatSpec documentation to each function to improve code readability and generate comprehensive documentation. This would be particularly helpful for developers using this harness for testing purposes.


1-78: Overall, the BridgeTransactionV2Harness contract is well-implemented.

The contract successfully serves its purpose as a test harness for BridgeTransactionV2Lib. All functions are correctly implemented, providing a clean and gas-efficient interface for testing the library's functionality.

To further improve the contract:

  1. Add NatSpec documentation to the contract and each function.
  2. Consider grouping related functions (e.g., origin-related, destination-related) using comments or regions for better organization.
  3. If applicable, add any relevant test helper functions that might be useful for common testing scenarios.
packages/contracts-rfq/test/FastBridgeV2.Src.Base.t.sol (2)

77-77: LGTM: Updated to use BridgeTransactionV2Lib.encodeV2.

The change correctly implements the new encoding method, which aligns with the PR objectives. The function signature remains unchanged, maintaining backward compatibility.

Consider adding a comment explaining the reason for using encodeV2 to improve code readability and maintainability.


Line range hint 1-108: Overall assessment: Consistent and well-implemented changes.

The updates in this file consistently implement the use of BridgeTransactionV2Lib.encodeV2 for encoding BridgeTransactionV2 structures. These changes align with the PR objectives of enhancing gas efficiency while maintaining backward compatibility. The code remains clean and readable, with only minor suggestions for improvement.

Consider adding a comment at the beginning of the file explaining the transition to BridgeTransactionV2Lib.encodeV2 and its benefits, to provide context for future developers working on this code.

packages/contracts-rfq/contracts/FastBridgeV2.sol (3)

Line range hint 285-314: Potential Reentrancy Vulnerability in claim Function

Similar to the refund function, the claim function has an external call token.universalTransfer(to, amount) at line 311. Emitting the event BridgeDepositClaimed after this external call may lead to inconsistencies if a reentrancy attack occurs. Emitting the event before the external call aligns with best practices and enhances security.

Apply this diff to move the event emission before the external call:

 bridgeTxDetails[transactionId].status = BridgeStatus.RELAYER_CLAIMED;

+emit BridgeDepositClaimed(transactionId, bridgeTxDetails[transactionId].proofRelayer, to, token, amount);

 // update protocol fees if origin fee amount exists
 address token = request.originToken();
 uint256 amount = request.originAmount();
 uint256 originFeeAmount = request.originFeeAmount();
 if (originFeeAmount > 0) protocolFees[token] += originFeeAmount;

 // transfer origin collateral less fee to specified address
 token.universalTransfer(to, amount);

418-430: Use of block.timestamp for Time Comparisons

In _validateRelayParams, block.timestamp is used for time comparisons at lines 424 and 427. While acceptable, it's important to note that miners can manipulate timestamps within a certain range. Ensure that the contract logic can tolerate slight deviations and that critical security decisions aren't solely dependent on precise timestamps.

🧰 Tools
🪛 GitHub Check: Slither

[notice] 418-430: Block timestamp
FastBridgeV2._validateRelayParams(bytes,bytes32,address) (contracts/FastBridgeV2.sol#418-430) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp > request.deadline() (contracts/FastBridgeV2.sol#424)
- exclRelayer != address(0) && exclRelayer != relayer && block.timestamp <= request.exclusivityEndTime() (contracts/FastBridgeV2.sol#427)


Line range hint 358-374: Gas Optimization in _checkedCallRecipient Function

The return data verification logic in _checkedCallRecipient is thorough but may benefit from gas optimization. Review the necessity of each check to identify potential simplifications that maintain security while reducing gas costs.

packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol (2)

428-433: Clarify the Invalid Request V2 Test Case

In the function test_relay_revert_invalidRequestV2, consider adding comments to explain why invalidRequestV2 is considered invalid. Providing context improves readability and helps future developers understand the purpose of the test.


465-470: Add Context to Invalid Request V2 with Relayer Address

In test_relay_withRelayerAddress_revert_invalidRequestV2, adding a comment to describe why invalidRequestV2 fails when used with a relayer address would enhance the test's clarity and maintainability.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3bad56c and 63822b0.

📒 Files selected for processing (11)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol (13 hunks)
  • packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol (1 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol (3 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol (2 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Encoding.t.sol (2 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.GasBench.Encoding.t.sol (2 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Src.Base.t.sol (3 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (3 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.t.sol (3 hunks)
  • packages/contracts-rfq/test/harnesses/BridgeTransactionV2Harness.sol (1 hunks)
  • packages/contracts-rfq/test/libs/BridgeTransactionV2.t.sol (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Slither
packages/contracts-rfq/contracts/FastBridgeV2.sol

[notice] 100-120: Reentrancy vulnerabilities
Reentrancy in FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#100-120):
External calls:
- token.universalTransfer(to,amount) (contracts/FastBridgeV2.sol#117)
Event emitted after the call(s):
- BridgeDepositRefunded(transactionId,to,token,amount) (contracts/FastBridgeV2.sol#119)


[notice] 100-120: Block timestamp
FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#100-120) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp <= deadline (contracts/FastBridgeV2.sol#109)


[notice] 285-314: Reentrancy vulnerabilities
Reentrancy in FastBridgeV2.claim(bytes,address) (contracts/FastBridgeV2.sol#285-314):
External calls:
- token.universalTransfer(to,amount) (contracts/FastBridgeV2.sol#311)
Event emitted after the call(s):
- BridgeDepositClaimed(transactionId,bridgeTxDetails[transactionId].proofRelayer,to,token,amount) (contracts/FastBridgeV2.sol#313)


[notice] 285-314: Block timestamp
FastBridgeV2.claim(bytes,address) (contracts/FastBridgeV2.sol#285-314) uses timestamp for comparisons
Dangerous comparisons:
- _timeSince(bridgeTxDetails[transactionId].proofBlockTimestamp) <= DISPUTE_PERIOD (contracts/FastBridgeV2.sol#298)


[notice] 418-430: Block timestamp
FastBridgeV2._validateRelayParams(bytes,bytes32,address) (contracts/FastBridgeV2.sol#418-430) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp > request.deadline() (contracts/FastBridgeV2.sol#424)
- exclRelayer != address(0) && exclRelayer != relayer && block.timestamp <= request.exclusivityEndTime() (contracts/FastBridgeV2.sol#427)

packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol

[warning] 112-117: Assembly usage
BridgeTransactionV2Lib.version(bytes) (contracts/libs/BridgeTransactionV2.sol#112-117) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#114-116)


[warning] 120-125: Assembly usage
BridgeTransactionV2Lib.originChainId(bytes) (contracts/libs/BridgeTransactionV2.sol#120-125) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#122-124)


[warning] 128-133: Assembly usage
BridgeTransactionV2Lib.destChainId(bytes) (contracts/libs/BridgeTransactionV2.sol#128-133) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#130-132)


[warning] 136-141: Assembly usage
BridgeTransactionV2Lib.originSender(bytes) (contracts/libs/BridgeTransactionV2.sol#136-141) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#138-140)


[warning] 144-149: Assembly usage
BridgeTransactionV2Lib.destRecipient(bytes) (contracts/libs/BridgeTransactionV2.sol#144-149) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#146-148)


[warning] 152-157: Assembly usage
BridgeTransactionV2Lib.originToken(bytes) (contracts/libs/BridgeTransactionV2.sol#152-157) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#154-156)


[warning] 160-165: Assembly usage
BridgeTransactionV2Lib.destToken(bytes) (contracts/libs/BridgeTransactionV2.sol#160-165) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#162-164)


[warning] 168-173: Assembly usage
BridgeTransactionV2Lib.originAmount(bytes) (contracts/libs/BridgeTransactionV2.sol#168-173) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#170-172)


[warning] 176-181: Assembly usage
BridgeTransactionV2Lib.destAmount(bytes) (contracts/libs/BridgeTransactionV2.sol#176-181) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#178-180)


[warning] 184-189: Assembly usage
BridgeTransactionV2Lib.originFeeAmount(bytes) (contracts/libs/BridgeTransactionV2.sol#184-189) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#186-188)


[warning] 192-197: Assembly usage
BridgeTransactionV2Lib.callValue(bytes) (contracts/libs/BridgeTransactionV2.sol#192-197) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#194-196)


[warning] 200-205: Assembly usage
BridgeTransactionV2Lib.deadline(bytes) (contracts/libs/BridgeTransactionV2.sol#200-205) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#202-204)


[warning] 208-213: Assembly usage
BridgeTransactionV2Lib.nonce(bytes) (contracts/libs/BridgeTransactionV2.sol#208-213) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#210-212)


[warning] 216-221: Assembly usage
BridgeTransactionV2Lib.exclusivityRelayer(bytes) (contracts/libs/BridgeTransactionV2.sol#216-221) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#218-220)


[warning] 224-229: Assembly usage
BridgeTransactionV2Lib.exclusivityEndTime(bytes) (contracts/libs/BridgeTransactionV2.sol#224-229) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#226-228)

🔇 Additional comments (32)
packages/contracts-rfq/test/FastBridgeV2.GasBench.Encoding.t.sol (2)

4-4: LGTM: New import statement added correctly.

The import of BridgeTransactionV2Lib is necessary for the changes in the test_getBridgeTransactionV2 function. The relative path appears to be correct.


Line range hint 1-24: Verify consistency across other test files.

The changes in this file are minimal but significant, aligning well with the PR objectives. To ensure consistency across the test suite:

  1. Check if other test files need similar updates to use BridgeTransactionV2Lib.
  2. Verify if there are other occurrences of abi.encode(tokenTx) that should be replaced with BridgeTransactionV2Lib.encodeV2(tokenTx).
packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol (3)

4-4: LGTM: New import added for BridgeTransactionV2Lib

The import of BridgeTransactionV2Lib is correctly added and is necessary for the changes in the relay and relayWithAddress functions.


48-51: LGTM: Consistent use of new encoding method

The change in relayWithAddress is consistent with the modification in the relay function, using BridgeTransactionV2Lib.encodeV2(bridgeTx) instead of abi.encode(bridgeTx). This ensures consistency in how BridgeTransactionV2 is encoded across different relay methods.


35-37: Verify the new encoding method for BridgeTransactionV2

The change from abi.encode(bridgeTx) to BridgeTransactionV2Lib.encodeV2(bridgeTx) looks good. This custom encoding method could potentially optimize gas usage or add version-specific encoding.

Please ensure that:

  1. The encodeV2 method in BridgeTransactionV2Lib correctly encodes all necessary fields of BridgeTransactionV2.
  2. The corresponding decoding method is implemented and tested.
  3. This change is consistent across all relevant parts of the codebase.

You can use the following script to verify the usage of encodeV2:

✅ Verification successful

BridgeTransactionV2Lib.encodeV2 Verified

The custom encoding method BridgeTransactionV2Lib.encodeV2 is used consistently across the codebase, and no instances of abi.encode(bridgeTx) remain.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of BridgeTransactionV2Lib.encodeV2

# Test: Search for all occurrences of encodeV2. Expect: Consistent usage across the codebase.
rg --type solidity -A 3 'BridgeTransactionV2Lib\.encodeV2'

# Test: Search for potential missed abi.encode calls for BridgeTransactionV2. Expect: No results.
rg --type solidity 'abi\.encode\(\s*bridgeTx\s*\)'

Length of output: 179


Script:

#!/bin/bash
# Description: Verify the usage of BridgeTransactionV2Lib.encodeV2

# Test: Search for all occurrences of encodeV2 in Solidity files. Expect: Consistent usage across the codebase.
rg -g "*.sol" -A 3 'BridgeTransactionV2Lib\.encodeV2'

# Test: Search for potential missed abi.encode calls for BridgeTransactionV2 in Solidity files. Expect: No results.
rg -g "*.sol" 'abi\.encode\(\s*bridgeTx\s*\)'

Length of output: 6221

packages/contracts-rfq/test/libs/BridgeTransactionV2.t.sol (1)

9-14: LGTM: Contract declaration and setup look good.

The contract structure and setUp function follow standard testing practices. The use of internal for the harness instance is appropriate, ensuring encapsulation while allowing derived contracts to access it if needed.

packages/contracts-rfq/test/FastBridgeV2.Encoding.t.sol (2)

4-5: LGTM: Import statement for BridgeTransactionV2Lib added.

The import of BridgeTransactionV2Lib is necessary for the updated encoding functions used in the test cases. This addition aligns with the changes made to support V2 transactions.


64-67: LGTM: Updated encoding for V2 transactions in test_getBridgeTransactionV2.

The change to use BridgeTransactionV2Lib.encodeV2 for encoding the request is consistent with the new encoding strategy for V2 transactions. This update ensures that the test case accurately reflects the behavior of the updated FastBridgeV2 contract.

packages/contracts-rfq/test/harnesses/BridgeTransactionV2Harness.sol (3)

1-6: LGTM: Contract structure and imports are well-defined.

The contract structure, license, Solidity version, and import statement are all appropriate and well-organized. The use of a relative path for imports enhances maintainability.


7-9: LGTM: encodeV2 function correctly wraps the library function.

The function signature and implementation are correct, providing a clean interface to the BridgeTransactionV2Lib.encodeV2 method.


11-13: LGTM: decodeV2 function correctly wraps the library function.

The function signature and implementation are correct, providing a clean interface to the BridgeTransactionV2Lib.decodeV2 method.

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

4-4: LGTM: New import statement added correctly.

The import of BridgeTransactionV2Lib is necessary for the updated encoding method used in the contract. The import statement is correctly formatted and placed appropriately in the file.


82-82: LGTM: Updated to use BridgeTransactionV2Lib.encodeV2.

The change correctly implements the new encoding method, consistent with the previous updates and aligning with the PR objectives. The function signature remains unchanged, maintaining backward compatibility.


87-87: LGTM: Updated to use BridgeTransactionV2Lib.encodeV2.

The change correctly implements the new encoding method, consistent with the previous updates and aligning with the PR objectives. The function signature remains unchanged, maintaining backward compatibility.

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

254-254: Appropriate Use of BridgeTransactionV2Lib.encodeV2 in getTxId

The getTxId function correctly utilizes BridgeTransactionV2Lib.encodeV2(bridgeTx) to generate a consistent transaction ID, ensuring alignment with the encoding used elsewhere.


261-264: New Helper Functions Enhance Test Clarity

The addition of expectRevertInvalidEncodedTx and expectRevertUnsupportedVersion functions improves test readability and reusability by encapsulating common revert expectations.

Also applies to: 265-269

packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol (6)

46-47: Clear and specific error handling

The error definitions BridgeTransactionV2__InvalidEncodedTx() and BridgeTransactionV2__UnsupportedVersion(uint16 version) provide precise error messages, enhancing code clarity and debugging efficiency.


51-57: Robust validation of encoded transactions

The validateV2 function correctly ensures that the encoded transaction meets the minimum length requirement and verifies the version. This preemptive validation enhances security and prevents decoding invalid data.


62-84: Efficient encoding with tight packing

The encodeV2 function effectively uses tight packing to encode the BridgeTransactionV2 struct, optimizing gas usage. Splitting the encoding into two parts to avoid the stack-too-deep error is a practical solution.


89-109: Comprehensive decoding of transaction fields

The decodeV2 function systematically decodes each field of the encoded transaction, ensuring all data is accurately retrieved. This methodical approach enhances reliability.


113-117: Appropriate use of inline assembly for data extraction

The functions (version, originChainId, destChainId, originSender, destRecipient, originToken, destToken, originAmount, destAmount, originFeeAmount, callValue, deadline, nonce, exclusivityRelayer, exclusivityEndTime) utilize inline assembly to extract data efficiently from the tightly packed encoded transaction. Given the need for precise control over calldata manipulation and gas optimization, the use of assembly is justified in this context.

Also applies to: 120-125, 128-133, 136-141, 144-149, 152-157, 160-165, 168-173, 176-181, 184-189, 192-197, 200-205, 208-213, 216-221, 224-229

🧰 Tools
🪛 GitHub Check: Slither

[warning] 112-117: Assembly usage
BridgeTransactionV2Lib.version(bytes) (contracts/libs/BridgeTransactionV2.sol#112-117) uses assembly
- INLINE ASM (contracts/libs/BridgeTransactionV2.sol#114-116)


231-234: Efficient slicing of calldata for callParams

The callParams function correctly slices the encodedTx to retrieve the dynamic callParams field, ensuring all remaining data is captured without additional computation.

packages/contracts-rfq/contracts/FastBridgeV2.sol (5)

7-7: Import and Usage of BridgeTransactionV2Lib

The inclusion of BridgeTransactionV2Lib and its application to bytes enhances code modularity and encapsulates the bridge transaction logic, improving maintainability and readability.

Also applies to: 18-18


66-69: Optimizing Function Parameters with calldata

Updating function parameters from bytes memory to bytes calldata in relay, prove, and claim functions improves gas efficiency by avoiding unnecessary memory allocation. This optimization is beneficial for contract performance.

Also applies to: 72-75, 78-81


Line range hint 134-157: Graceful Handling of Transaction Decoding in getBridgeTransaction

Employing a try-catch block to decode the request using getBridgeTransactionV2 and falling back to V1 decoding ensures backward compatibility. This approach is robust and allows seamless integration of the new V2 structure without disrupting existing functionality.


158-162: Addition of getBridgeTransactionV2 Function

Introducing the getBridgeTransactionV2 function provides a dedicated method to decode V2 bridge transactions. This addition enhances clarity and modularity, promoting better code organization.


Line range hint 179-200: Utilization of BridgeTransactionV2Lib.encodeV2 in bridge Function

Updating the bridge function to use BridgeTransactionV2Lib.encodeV2 for encoding requests centralizes the encoding logic. This change improves code reuse and maintainability by leveraging the library's capabilities.

packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol (2)

434-438: Verify the Placement of vm.prank Call

In test_relay_revert_requestV3, ensure that the vm.prank call is correctly placed and included in the changed lines. Omitting changes in setup functions like vm.prank may lead to incomplete test configurations.

To confirm, run the following script to check the use of vm.prank in version-related test functions:

✅ Verification successful

vm.prank Placement Verified Successfully

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that vm.prank calls are properly placed in version-related tests.

# Test: Search for vm.prank calls in test_relay_revert_requestV3 function.
# Expect: vm.prank call should be immediately before the relay call.
ast-grep --lang solidity --pattern $'function test_relay_revert_requestV3() {
  $$$
  vm.prank($_);
  $$$
}'

Length of output: 226


Script:

#!/bin/bash
# Description: Verify that vm.prank calls are properly placed in version-related tests.

# Extract lines from the test_relay_revert_requestV3 function
rg -A5 'function test_relay_revert_requestV3\(\)' packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol > function_lines.txt

# Check if vm.prank is immediately before fastBridge.relay
prank_line=$(grep -n 'vm\.prank' function_lines.txt | cut -d: -f1)
relay_line=$(grep -n 'fastBridge\.relay' function_lines.txt | cut -d: -f1)

if [ "$prank_line" ] && [ "$relay_line" ]; then
  difference=$((relay_line - prank_line))
  if [ "$difference" -eq 1 ]; then
    echo "vm.prank is correctly placed immediately before fastBridge.relay."
  else
    echo "vm.prank is not immediately before fastBridge.relay."
  fi
else
  echo "Required function calls not found."
fi

Length of output: 452


471-475: Verify Correct Usage of vm.prank in V3 Test

Similar to previous observations, in test_relay_withRelayerAddress_revert_requestV3, confirm that the vm.prank call is correctly positioned and fully included in the changes. This ensures the test accurately simulates the intended caller context.

Use the script below to validate the placement of vm.prank:

✅ Verification successful

vm.prank Correctly Precedes relay Call in test_relay_withRelayerAddress_revert_requestV3

The vm.prank call is correctly positioned before the relay function call within the test_relay_withRelayerAddress_revert_requestV3 function.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify vm.prank call placement in test_relay_withRelayerAddress_revert_requestV3.

# Test: Ensure vm.prank is used correctly in the test function.
# Expect: vm.prank call should precede the relay function call.
ast-grep --lang solidity --pattern $'function test_relay_withRelayerAddress_revert_requestV3() {
  $$$
  vm.prank($_);
  $$$
}'

Length of output: 245


Script:

#!/bin/bash
# Description: Verify the placement of vm.prank in test_relay_withRelayerAddress_revert_requestV3 using ripgrep.

# Extract the block of the specific test function
rg -A 10 'function test_relay_withRelayerAddress_revert_requestV3\(\)' packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol

# Within the extracted block, check the order of vm.prank and relay calls
# This assumes the function block does not exceed 10 lines after the function declaration
rg -A 10 'function test_relay_withRelayerAddress_revert_requestV3\(\)' packages/contracts-rfq/test/FastBridgeV2.Dst.t.sol | grep -E 'vm\.prank|fastBridge\.relay'

Length of output: 895

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

4-4: Proper import of BridgeTransactionV2Lib

The addition of import {BridgeTransactionV2Lib} from "../contracts/libs/BridgeTransactionV2.sol"; correctly incorporates the necessary library for encoding bridge transactions. This ensures that the encodeV2 function is available for use within the contract.


41-41: Correct usage of BridgeTransactionV2Lib.encodeV2

The update in the expectBridgeRequested function to use BridgeTransactionV2Lib.encodeV2(bridgeTx) enhances the encoding of bridge transaction requests. This change aligns with the new encoding standards and ensures consistency across the contract.


919-993: Comprehensive testing of invalid payloads and unsupported versions

The newly added test functions from test_prove_revert_requestV1 to test_refund_revert_requestV3 effectively cover scenarios involving unsupported versions and invalid encoded transactions for the prove, claim, and refund functions. These tests enhance the robustness of the contract by ensuring that it correctly reverts when handling such edge cases.

packages/contracts-rfq/test/FastBridgeV2.t.sol Outdated Show resolved Hide resolved
packages/contracts-rfq/test/FastBridgeV2.t.sol Outdated Show resolved Hide resolved
Comment on lines 100 to 118
function refund(bytes calldata request) external {
request.validateV2();
bytes32 transactionId = keccak256(request);

BridgeTransactionV2 memory transaction = getBridgeTransactionV2(request);

if (bridgeTxDetails[transactionId].status != BridgeStatus.REQUESTED) revert StatusIncorrect();

if (hasRole(REFUNDER_ROLE, msg.sender)) {
// Refunder can refund if deadline has passed
if (block.timestamp <= transaction.deadline) revert DeadlineNotExceeded();
} else {
// Permissionless refund is allowed after REFUND_DELAY
if (block.timestamp <= transaction.deadline + REFUND_DELAY) revert DeadlineNotExceeded();
}

uint256 deadline = request.deadline();
// Permissionless refund is allowed after REFUND_DELAY
if (!hasRole(REFUNDER_ROLE, msg.sender)) deadline += REFUND_DELAY;
if (block.timestamp <= deadline) revert DeadlineNotExceeded();
// if all checks passed, set to REFUNDED status
bridgeTxDetails[transactionId].status = BridgeStatus.REFUNDED;

// transfer origin collateral back to original sender
address to = transaction.originSender;
address token = transaction.originToken;
uint256 amount = transaction.originAmount + transaction.originFeeAmount;
address to = request.originSender();
address token = request.originToken();
uint256 amount = request.originAmount() + request.originFeeAmount();
token.universalTransfer(to, amount);

Copy link
Contributor

@coderabbitai coderabbitai bot Oct 14, 2024

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential Reentrancy Vulnerability in refund Function

There's a potential reentrancy issue in the refund function due to the external call token.universalTransfer(to, amount) at line 117. While the state update occurs before the external call, emitting the event BridgeDepositRefunded after the external call could pose risks. It's best practice to emit events before external calls to ensure accurate state representation, even if a reentrancy attack occurs.

Apply this diff to move the event emission before the external call:

 bridgeTxDetails[transactionId].status = BridgeStatus.REFUNDED;

+emit BridgeDepositRefunded(transactionId, to, token, amount);

 // transfer origin collateral back to original sender
 address to = request.originSender();
 address token = request.originToken();
 uint256 amount = request.originAmount() + request.originFeeAmount();
 token.universalTransfer(to, amount);
📝 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 refund(bytes calldata request) external {
request.validateV2();
bytes32 transactionId = keccak256(request);
BridgeTransactionV2 memory transaction = getBridgeTransactionV2(request);
if (bridgeTxDetails[transactionId].status != BridgeStatus.REQUESTED) revert StatusIncorrect();
if (hasRole(REFUNDER_ROLE, msg.sender)) {
// Refunder can refund if deadline has passed
if (block.timestamp <= transaction.deadline) revert DeadlineNotExceeded();
} else {
// Permissionless refund is allowed after REFUND_DELAY
if (block.timestamp <= transaction.deadline + REFUND_DELAY) revert DeadlineNotExceeded();
}
uint256 deadline = request.deadline();
// Permissionless refund is allowed after REFUND_DELAY
if (!hasRole(REFUNDER_ROLE, msg.sender)) deadline += REFUND_DELAY;
if (block.timestamp <= deadline) revert DeadlineNotExceeded();
// if all checks passed, set to REFUNDED status
bridgeTxDetails[transactionId].status = BridgeStatus.REFUNDED;
// transfer origin collateral back to original sender
address to = transaction.originSender;
address token = transaction.originToken;
uint256 amount = transaction.originAmount + transaction.originFeeAmount;
address to = request.originSender();
address token = request.originToken();
uint256 amount = request.originAmount() + request.originFeeAmount();
token.universalTransfer(to, amount);
function refund(bytes calldata request) external {
request.validateV2();
bytes32 transactionId = keccak256(request);
if (bridgeTxDetails[transactionId].status != BridgeStatus.REQUESTED) revert StatusIncorrect();
uint256 deadline = request.deadline();
// Permissionless refund is allowed after REFUND_DELAY
if (!hasRole(REFUNDER_ROLE, msg.sender)) deadline += REFUND_DELAY;
if (block.timestamp <= deadline) revert DeadlineNotExceeded();
// if all checks passed, set to REFUNDED status
bridgeTxDetails[transactionId].status = BridgeStatus.REFUNDED;
emit BridgeDepositRefunded(transactionId, to, token, amount);
// transfer origin collateral back to original sender
address to = request.originSender();
address token = request.originToken();
uint256 amount = request.originAmount() + request.originFeeAmount();
token.universalTransfer(to, amount);
🧰 Tools
🪛 GitHub Check: Slither

[notice] 100-120: Reentrancy vulnerabilities
Reentrancy in FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#100-120):
External calls:
- token.universalTransfer(to,amount) (contracts/FastBridgeV2.sol#117)
Event emitted after the call(s):
- BridgeDepositRefunded(transactionId,to,token,amount) (contracts/FastBridgeV2.sol#119)


[notice] 100-120: Block timestamp
FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#100-120) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp <= deadline (contracts/FastBridgeV2.sol#109)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is a valid, yet niche find. The PR is question doesn't change the way refund (or any other state-chanigng functions) works as far as the contract is concerned, so this is out of scope of the particular PR. This is now tracked as SLT-342 in the internal ticket system.

Copy link
Contributor

Choose a reason for hiding this comment

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

@ChiTimesChi, understood. Thank you for tracking this issue in SLT-342.

(_/)
( •_•)
(>🕳 )


✏️ Learnings added
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/contracts/FastBridgeV2.sol:100-118
Timestamp: 2024-10-14T14:45:57.032Z
Learning: When reviewing code in `packages/contracts-rfq/contracts/FastBridgeV2.sol` (Solidity), focus on changes introduced in the PR and avoid commenting on existing functions like `refund` if they are not modified by the PR, as such comments are considered out of scope.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

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 ec0ba1a and 3555d77.

📒 Files selected for processing (4)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol (14 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol (3 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (3 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.t.sol (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol
  • packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol
🧰 Additional context used
📓 Learnings (3)
📓 Common learnings
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/contracts/FastBridgeV2.sol:100-118
Timestamp: 2024-10-14T14:45:57.214Z
Learning: When reviewing code in `packages/contracts-rfq/contracts/FastBridgeV2.sol` (Solidity), focus on changes introduced in the PR and avoid commenting on existing functions like `refund` if they are not modified by the PR, as such comments are considered out of scope.
packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (5)
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/test/FastBridgeV2.Src.t.sol:919-993
Timestamp: 2024-10-14T14:48:01.520Z
Learning: In Solidity test files for FastBridgeV2 (e.g., `packages/contracts-rfq/test/FastBridgeV2.Src.t.sol`), code duplication in test functions is acceptable to maintain readability and maintainability, even if it contradicts DRY principles.
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/test/FastBridgeV2.Src.Base.t.sol:97-97
Timestamp: 2024-10-14T13:23:04.509Z
Learning: In `packages/contracts-rfq/test/FastBridgeV2.t.sol`, when testing expected revert behaviors, `abi.encodeWithSelector` is used with custom errors and should not be replaced with `BridgeTransactionV2Lib.encodeV2`.
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/test/FastBridgeV2.t.sol:53-56
Timestamp: 2024-10-14T13:24:45.293Z
Learning: Modifying test utility contracts in the `test` directory is unnecessary and would only pollute the code.
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/contracts/FastBridgeV2.sol:100-118
Timestamp: 2024-10-14T14:45:57.214Z
Learning: When reviewing code in `packages/contracts-rfq/contracts/FastBridgeV2.sol` (Solidity), focus on changes introduced in the PR and avoid commenting on existing functions like `refund` if they are not modified by the PR, as such comments are considered out of scope.
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/test/FastBridgeV2.t.sol:53-56
Timestamp: 2024-10-14T13:24:45.293Z
Learning: In Solidity test contracts under the `test` directory, such as `FastBridgeV2.t.sol`, contracts are not deployed, so gas consumption is not a concern.
packages/contracts-rfq/test/FastBridgeV2.t.sol (4)
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/test/FastBridgeV2.t.sol:53-56
Timestamp: 2024-10-14T13:24:45.293Z
Learning: Modifying test utility contracts in the `test` directory is unnecessary and would only pollute the code.
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/test/FastBridgeV2.t.sol:53-56
Timestamp: 2024-10-14T13:24:45.293Z
Learning: In Solidity test contracts under the `test` directory, such as `FastBridgeV2.t.sol`, contracts are not deployed, so gas consumption is not a concern.
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/test/FastBridgeV2.Src.t.sol:919-993
Timestamp: 2024-10-14T14:48:01.520Z
Learning: In Solidity test files for FastBridgeV2 (e.g., `packages/contracts-rfq/test/FastBridgeV2.Src.t.sol`), code duplication in test functions is acceptable to maintain readability and maintainability, even if it contradicts DRY principles.
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/test/FastBridgeV2.Src.Base.t.sol:97-97
Timestamp: 2024-10-14T13:23:04.509Z
Learning: In `packages/contracts-rfq/test/FastBridgeV2.t.sol`, when testing expected revert behaviors, `abi.encodeWithSelector` is used with custom errors and should not be replaced with `BridgeTransactionV2Lib.encodeV2`.
🔇 Additional comments (9)
packages/contracts-rfq/test/FastBridgeV2.t.sol (6)

4-5: Importing BridgeTransactionV2Lib for Transaction Encoding

The import statement correctly includes the BridgeTransactionV2Lib library for bridge transaction encoding and decoding, aligning with the updates to the transaction structures.


49-52: Declaration of Internal Byte Arrays for Mock Requests

The internal byte arrays mockRequestV1, invalidRequestV2, and mockRequestV3 are appropriately declared for use in test scenarios involving different versions of bridge transactions.


79-84: Initialize Mock Requests Appropriately in setUp Function

The initialization of mockRequestV1, invalidRequestV2, and mockRequestV3 in the setUp function is correctly timed. Forming invalidRequestV2 before createFixturesV2() and mockRequestV3 after ensures that they use the intended parameters for testing.


267-267: Utilize encodeV2 for Consistent Transaction Hashing

Updating the getTxId function to use BridgeTransactionV2Lib.encodeV2(bridgeTx) ensures that the transaction ID is computed using the standardized V2 encoding, enhancing consistency across the bridge transaction processes.


274-276: Add expectRevertInvalidEncodedTx for Specific Revert Testing

The expectRevertInvalidEncodedTx function correctly sets up an expectation for reverts due to invalid encoded transactions by referencing the appropriate selector from BridgeTransactionV2Lib.


278-282: Implement expectRevertUnsupportedVersion for Version Handling Tests

The expectRevertUnsupportedVersion function is properly designed to expect reverts when an unsupported version is encountered, utilizing abi.encodeWithSelector to pass the version parameter.

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

4-5: Importing BridgeTransactionV2Lib enhances transaction encoding capabilities

The addition of the BridgeTransactionV2Lib import allows the use of encodeV2, which improves the encoding and decoding processes for bridge transactions. This aligns with the updates made to the FastBridgeV2 contract for better efficiency and maintainability.


41-41: Utilizing encodeV2 for request encoding ensures version consistency

By updating the request field to use BridgeTransactionV2Lib.encodeV2(bridgeTx), the code now correctly encodes the bridge transaction according to the new versioning system. This change enhances consistency and prepares the contract for future versions.


918-992: Comprehensive tests added for invalid payload scenarios

The newly added test functions effectively cover cases of unsupported versions and invalid encoded transactions for the prove, claim, and refund methods. These tests ensure that the contract correctly reverts when handling invalid inputs, enhancing the robustness and reliability of the system.

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/contracts/libs/BridgeTransactionV2.sol (3)

1-7: LGTM! Consider adding a brief library description.

The library declaration, license, and pragma statements are correct. The import statement is appropriately used.

Consider adding a brief comment above the library declaration to explain its purpose and how it relates to BridgeTransactionV2. This would enhance code readability and maintainability.


59-87: LGTM! Well-implemented encoding function.

The encodeV2 function effectively encodes the BridgeTransactionV2 struct by tightly packing the fields. The splitting of encoding into two parts is a good practice to avoid stack-too-deep errors.

Consider adding a comment about the return value type, such as:

/// @return The tightly packed encoded transaction as bytes.

This would provide clarity on the function's output.


1-238: LGTM! Well-implemented and gas-efficient library.

The BridgeTransactionV2Lib is well-structured, gas-efficient, and follows good Solidity development practices. The use of tight packing and inline assembly is appropriate for the use case.

Consider adding natspec comments for all public functions to improve documentation. This would include adding @param and @return descriptions where applicable.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3555d77 and 5bce10b.

📒 Files selected for processing (2)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol (15 hunks)
  • packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol (1 hunks)
🧰 Additional context used
📓 Learnings (2)
📓 Common learnings
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/contracts/FastBridgeV2.sol:100-118
Timestamp: 2024-10-14T14:45:57.214Z
Learning: When reviewing code in `packages/contracts-rfq/contracts/FastBridgeV2.sol` (Solidity), focus on changes introduced in the PR and avoid commenting on existing functions like `refund` if they are not modified by the PR, as such comments are considered out of scope.
packages/contracts-rfq/contracts/FastBridgeV2.sol (1)
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/contracts/FastBridgeV2.sol:100-118
Timestamp: 2024-10-14T14:45:57.214Z
Learning: When reviewing code in `packages/contracts-rfq/contracts/FastBridgeV2.sol` (Solidity), focus on changes introduced in the PR and avoid commenting on existing functions like `refund` if they are not modified by the PR, as such comments are considered out of scope.
🪛 GitHub Check: Slither
packages/contracts-rfq/contracts/FastBridgeV2.sol

[notice] 102-126: Reentrancy vulnerabilities
Reentrancy in FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#102-126):
External calls:
- Address.sendValue(address(to),amount) (contracts/FastBridgeV2.sol#120)
- IERC20(token).safeTransfer(to,amount) (contracts/FastBridgeV2.sol#122)
Event emitted after the call(s):
- BridgeDepositRefunded(transactionId,to,token,amount) (contracts/FastBridgeV2.sol#125)


[notice] 102-126: Block timestamp
FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#102-126) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp <= deadline (contracts/FastBridgeV2.sol#111)


[notice] 293-326: Reentrancy vulnerabilities
Reentrancy in FastBridgeV2.claim(bytes,address) (contracts/FastBridgeV2.sol#293-326):
External calls:
- Address.sendValue(address(to),amount) (contracts/FastBridgeV2.sol#320)
- IERC20(token).safeTransfer(to,amount) (contracts/FastBridgeV2.sol#322)
Event emitted after the call(s):
- BridgeDepositClaimed(transactionId,bridgeTxDetails[transactionId].proofRelayer,to,token,amount) (contracts/FastBridgeV2.sol#325)


[notice] 293-326: Block timestamp
FastBridgeV2.claim(bytes,address) (contracts/FastBridgeV2.sol#293-326) uses timestamp for comparisons
Dangerous comparisons:
- _timeSince(bridgeTxDetails[transactionId].proofBlockTimestamp) <= DISPUTE_PERIOD (contracts/FastBridgeV2.sol#306)


[notice] 430-442: Block timestamp
FastBridgeV2._validateRelayParams(bytes,bytes32,address) (contracts/FastBridgeV2.sol#430-442) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp > request.deadline() (contracts/FastBridgeV2.sol#436)
- exclRelayer != address(0) && exclRelayer != relayer && block.timestamp <= request.exclusivityEndTime() (contracts/FastBridgeV2.sol#439)

🔇 Additional comments (10)
packages/contracts-rfq/contracts/libs/BridgeTransactionV2.sol (6)

8-44: LGTM! Well-structured constant definitions.

The constant definitions for VERSION and field offsets are well-organized and clearly commented. The use of tight packing for struct fields is an excellent optimization for gas efficiency.


46-47: LGTM! Well-defined custom errors.

The custom error definitions are appropriate and follow good naming conventions. They provide clear and gas-efficient error handling for invalid transactions and unsupported versions.


49-57: LGTM! Robust validation function.

The validateV2 function effectively checks the minimum length and version of the encoded transaction. It uses custom errors appropriately and ensures all static fields are present before accessing the version.


89-112: LGTM! Well-structured decoding function.

The decodeV2 function effectively decodes the BridgeTransactionV2 struct from the encoded transaction. The use of individual extraction functions for each field promotes code modularity and reusability.


114-120: LGTM! Efficient version extraction.

The version function efficiently extracts the version from the encoded transaction using inline assembly. This approach is appropriate for the required bit manipulation.

Note: This approval applies to all similar extraction functions in the library (lines 114-232), as they follow the same pattern of efficient data extraction using inline assembly.


234-237: LGTM! Simple and effective callParams extraction.

The callParams function efficiently extracts the call params from the encoded transaction using a simple slice operation. This approach is appropriate and more readable than using inline assembly for this particular case.

packages/contracts-rfq/contracts/FastBridgeV2.sol (4)

7-7: Good use of BridgeTransactionV2Lib for modularity and maintainability

The import and utilization of BridgeTransactionV2Lib enhance code modularity by centralizing the encoding and decoding logic for BridgeTransactionV2. This improves maintainability and reduces code duplication.

Also applies to: 18-18


66-66: Optimizing gas usage by changing parameters to calldata

Updating function parameters from bytes memory to bytes calldata in functions like relay, prove, claim, and refund enhances gas efficiency by avoiding unnecessary memory allocations. This optimization leads to cost savings during contract execution.

Also applies to: 72-72, 78-78, 102-102, 140-140, 164-165, 225-225, 293-293


Line range hint 140-156: Ensuring backward compatibility with legacy transaction formats

The implementation of a try-catch block in getBridgeTransaction allows the contract to handle both V1 and V2 transaction formats gracefully. By attempting to decode with getBridgeTransactionV2 and falling back to V1 decoding if it fails, you ensure backward compatibility and a smooth transition for users relying on older transaction structures.


Line range hint 187-203: Consistent request encoding using BridgeTransactionV2Lib.encodeV2

Utilizing BridgeTransactionV2Lib.encodeV2 in the bridge function ensures consistent and reliable serialization of request data. This approach standardizes the encoding process, reducing potential errors and simplifying future maintenance.

Copy link
Collaborator

@parodime parodime left a comment

Choose a reason for hiding this comment

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

good catch on the token/originFeeAmt updates that I missed on claim() in my other PR -- thanks

everything LGTM

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 and nitpick comments (1)
packages/contracts-rfq/contracts/FastBridgeV2.sol (1)

Line range hint 303-341: Potential Reentrancy Vulnerability in claim Function

Similar to the refund function, the claim function could be vulnerable to reentrancy attacks because external calls to Address.sendValue or IERC20(token).safeTransfer are made before emitting the BridgeDepositClaimed event. To adhere to the checks-effects-interactions pattern, consider emitting the event before the external calls.

Apply this diff to move the event emission before the external calls:

 // Note: this is a storage write
 $.status = BridgeStatus.RELAYER_CLAIMED;

+emit BridgeDepositClaimed(transactionId, proofRelayer, to, token, amount);

 // update protocol fees if origin fee amount exists
 address token = request.originToken();
 uint256 amount = request.originAmount();
 uint256 originFeeAmount = request.originFeeAmount();
 if (originFeeAmount > 0) protocolFees[token] += originFeeAmount;

 // transfer origin collateral to specified address (protocol fee was pre-deducted at deposit)
 if (token == UniversalTokenLib.ETH_ADDRESS) {
     Address.sendValue(payable(to), amount);
 } else {
     IERC20(token).safeTransfer(to, amount);
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 5bce10b and 2c18409.

📒 Files selected for processing (1)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol (15 hunks)
🧰 Additional context used
📓 Learnings (2)
📓 Common learnings
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/contracts/FastBridgeV2.sol:100-118
Timestamp: 2024-10-14T14:45:57.214Z
Learning: When reviewing code in `packages/contracts-rfq/contracts/FastBridgeV2.sol` (Solidity), focus on changes introduced in the PR and avoid commenting on existing functions like `refund` if they are not modified by the PR, as such comments are considered out of scope.
packages/contracts-rfq/contracts/FastBridgeV2.sol (1)
Learnt from: ChiTimesChi
PR: synapsecns/sanguine#3284
File: packages/contracts-rfq/contracts/FastBridgeV2.sol:100-118
Timestamp: 2024-10-14T14:45:57.214Z
Learning: When reviewing code in `packages/contracts-rfq/contracts/FastBridgeV2.sol` (Solidity), focus on changes introduced in the PR and avoid commenting on existing functions like `refund` if they are not modified by the PR, as such comments are considered out of scope.
🪛 GitHub Check: Slither
packages/contracts-rfq/contracts/FastBridgeV2.sol

[notice] 106-131: Reentrancy vulnerabilities
Reentrancy in FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#106-131):
External calls:
- Address.sendValue(address(to),amount) (contracts/FastBridgeV2.sol#125)
- IERC20(token).safeTransfer(to,amount) (contracts/FastBridgeV2.sol#127)
Event emitted after the call(s):
- BridgeDepositRefunded(transactionId,to,token,amount) (contracts/FastBridgeV2.sol#130)


[notice] 106-131: Block timestamp
FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#106-131) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp <= deadline (contracts/FastBridgeV2.sol#116)


[notice] 303-342: Reentrancy vulnerabilities
Reentrancy in FastBridgeV2.claim(bytes,address) (contracts/FastBridgeV2.sol#303-342):
External calls:
- Address.sendValue(address(to),amount) (contracts/FastBridgeV2.sol#336)
- IERC20(token).safeTransfer(to,amount) (contracts/FastBridgeV2.sol#338)
Event emitted after the call(s):
- BridgeDepositClaimed(transactionId,proofRelayer,to,token,amount) (contracts/FastBridgeV2.sol#341)


[notice] 303-342: Block timestamp
FastBridgeV2.claim(bytes,address) (contracts/FastBridgeV2.sol#303-342) uses timestamp for comparisons
Dangerous comparisons:
- _timeSince(proofBlockTimestamp) <= DISPUTE_PERIOD (contracts/FastBridgeV2.sol#322)


[notice] 448-460: Block timestamp
FastBridgeV2._validateRelayParams(bytes,bytes32,address) (contracts/FastBridgeV2.sol#448-460) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp > request.deadline() (contracts/FastBridgeV2.sol#454)
- exclRelayer != address(0) && exclRelayer != relayer && block.timestamp <= request.exclusivityEndTime() (contracts/FastBridgeV2.sol#457)

🔇 Additional comments (2)
packages/contracts-rfq/contracts/FastBridgeV2.sol (2)

66-67: Optimizing Gas Usage by Switching to calldata

Great work on updating the function parameters in relay, prove, and claim to use bytes calldata instead of bytes memory. This change enhances gas efficiency by reducing unnecessary memory allocations.

Also applies to: 72-73, 78-79


Line range hint 194-210: Utilizing BridgeTransactionV2Lib.encodeV2 for Consistent Encoding

Excellent implementation of BridgeTransactionV2Lib.encodeV2 in the bridge function. This promotes consistency and reduces potential errors in encoding bridge transactions.

Comment on lines +106 to +130
function refund(bytes calldata request) external {
request.validateV2();
bytes32 transactionId = keccak256(request);

BridgeTransactionV2 memory transaction = getBridgeTransactionV2(request);

BridgeTxDetails storage $ = bridgeTxDetails[transactionId];

if ($.status != BridgeStatus.REQUESTED) revert StatusIncorrect();

if (hasRole(REFUNDER_ROLE, msg.sender)) {
// Refunder can refund if deadline has passed
if (block.timestamp <= transaction.deadline) revert DeadlineNotExceeded();
} else {
// Permissionless refund is allowed after REFUND_DELAY
if (block.timestamp <= transaction.deadline + REFUND_DELAY) revert DeadlineNotExceeded();
}

uint256 deadline = request.deadline();
// Permissionless refund is allowed after REFUND_DELAY
if (!hasRole(REFUNDER_ROLE, msg.sender)) deadline += REFUND_DELAY;
if (block.timestamp <= deadline) revert DeadlineNotExceeded();
// Note: this is a storage write
$.status = BridgeStatus.REFUNDED;

// transfer origin collateral back to original sender
uint256 amount = transaction.originAmount + transaction.originFeeAmount;
address to = transaction.originSender;
address token = transaction.originToken;

address to = request.originSender();
address token = request.originToken();
uint256 amount = request.originAmount() + request.originFeeAmount();
if (token == UniversalTokenLib.ETH_ADDRESS) {
Address.sendValue(payable(to), amount);
} else {
IERC20(token).safeTransfer(to, amount);
}

emit BridgeDepositRefunded(transactionId, transaction.originSender, transaction.originToken, amount);
emit BridgeDepositRefunded(transactionId, to, token, amount);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Potential Reentrancy Vulnerability in refund Function

The refund function may be susceptible to reentrancy attacks due to external calls to Address.sendValue or IERC20(token).safeTransfer before emitting the BridgeDepositRefunded event. To mitigate this risk, it's best practice to update the state and emit events before making external calls.

Apply this diff to move the event emission before the external calls:

 // Note: this is a storage write
 $.status = BridgeStatus.REFUNDED;

+emit BridgeDepositRefunded(transactionId, to, token, amount);

 // transfer origin collateral back to original sender
 address to = request.originSender();
 address token = request.originToken();
 uint256 amount = request.originAmount() + request.originFeeAmount();
 if (token == UniversalTokenLib.ETH_ADDRESS) {
     Address.sendValue(payable(to), amount);
 } else {
     IERC20(token).safeTransfer(to, amount);
 }
📝 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 refund(bytes calldata request) external {
request.validateV2();
bytes32 transactionId = keccak256(request);
BridgeTransactionV2 memory transaction = getBridgeTransactionV2(request);
BridgeTxDetails storage $ = bridgeTxDetails[transactionId];
if ($.status != BridgeStatus.REQUESTED) revert StatusIncorrect();
if (hasRole(REFUNDER_ROLE, msg.sender)) {
// Refunder can refund if deadline has passed
if (block.timestamp <= transaction.deadline) revert DeadlineNotExceeded();
} else {
// Permissionless refund is allowed after REFUND_DELAY
if (block.timestamp <= transaction.deadline + REFUND_DELAY) revert DeadlineNotExceeded();
}
uint256 deadline = request.deadline();
// Permissionless refund is allowed after REFUND_DELAY
if (!hasRole(REFUNDER_ROLE, msg.sender)) deadline += REFUND_DELAY;
if (block.timestamp <= deadline) revert DeadlineNotExceeded();
// Note: this is a storage write
$.status = BridgeStatus.REFUNDED;
// transfer origin collateral back to original sender
uint256 amount = transaction.originAmount + transaction.originFeeAmount;
address to = transaction.originSender;
address token = transaction.originToken;
address to = request.originSender();
address token = request.originToken();
uint256 amount = request.originAmount() + request.originFeeAmount();
if (token == UniversalTokenLib.ETH_ADDRESS) {
Address.sendValue(payable(to), amount);
} else {
IERC20(token).safeTransfer(to, amount);
}
emit BridgeDepositRefunded(transactionId, transaction.originSender, transaction.originToken, amount);
emit BridgeDepositRefunded(transactionId, to, token, amount);
function refund(bytes calldata request) external {
request.validateV2();
bytes32 transactionId = keccak256(request);
BridgeTxDetails storage $ = bridgeTxDetails[transactionId];
if ($.status != BridgeStatus.REQUESTED) revert StatusIncorrect();
uint256 deadline = request.deadline();
// Permissionless refund is allowed after REFUND_DELAY
if (!hasRole(REFUNDER_ROLE, msg.sender)) deadline += REFUND_DELAY;
if (block.timestamp <= deadline) revert DeadlineNotExceeded();
// Note: this is a storage write
$.status = BridgeStatus.REFUNDED;
emit BridgeDepositRefunded(transactionId, to, token, amount);
// transfer origin collateral back to original sender
address to = request.originSender();
address token = request.originToken();
uint256 amount = request.originAmount() + request.originFeeAmount();
if (token == UniversalTokenLib.ETH_ADDRESS) {
Address.sendValue(payable(to), amount);
} else {
IERC20(token).safeTransfer(to, amount);
}
🧰 Tools
🪛 GitHub Check: Slither

[notice] 106-131: Reentrancy vulnerabilities
Reentrancy in FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#106-131):
External calls:
- Address.sendValue(address(to),amount) (contracts/FastBridgeV2.sol#125)
- IERC20(token).safeTransfer(to,amount) (contracts/FastBridgeV2.sol#127)
Event emitted after the call(s):
- BridgeDepositRefunded(transactionId,to,token,amount) (contracts/FastBridgeV2.sol#130)


[notice] 106-131: Block timestamp
FastBridgeV2.refund(bytes) (contracts/FastBridgeV2.sol#106-131) uses timestamp for comparisons
Dangerous comparisons:
- block.timestamp <= deadline (contracts/FastBridgeV2.sol#116)

Copy link
Contributor

@trajan0x trajan0x left a comment

Choose a reason for hiding this comment

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

LGTM

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.

3 participants