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

FbV2 sender nonces [SLT-183] #3214

Merged
merged 4 commits into from
Oct 2, 2024
Merged

FbV2 sender nonces [SLT-183] #3214

merged 4 commits into from
Oct 2, 2024

Conversation

parodime
Copy link
Collaborator

@parodime parodime commented Oct 2, 2024

Description
Replace chain-scoped nonce with one that increments per-sender

Additional context
Reduces risk of reorgs resulting in a different nonce

Summary by CodeRabbit

  • New Features

    • Enhanced nonce management for improved security, allowing unique tracking per sender.
    • Deprecated the old nonce mechanism, introducing a new public function that always returns zero.
  • Bug Fixes

    • Added assertions to ensure correct nonce incrementing for users during bridge operations.
  • Documentation

    • Updated comments to reflect changes in nonce management and deprecation notices.

@parodime parodime requested a review from ChiTimesChi as a code owner October 2, 2024 16:09
Copy link
Contributor

coderabbitai bot commented Oct 2, 2024

Walkthrough

The .gitignore file in the packages/contracts-rfq directory has been updated to ignore lcov.info. Additionally, the FastBridgeV2 contract has undergone significant changes to its nonce management system, replacing the single nonce variable with a mapping called senderNonces for tracking nonces per sender. The deprecated nonce variable is now an immutable constant initialized to zero. Test contracts have also been modified to include assertions that verify the correct behavior of the new nonce system during bridge operations.

Changes

File Path Change Summary
packages/contracts-rfq/.gitignore - Added lcov.info to the ignore list.
packages/contracts-rfq/contracts/FastBridgeV2.sol - Replaced uint256 public nonce with mapping(address => uint256) public senderNonces.
- Added function nonce() external pure returns (uint256).
packages/contracts-rfq/test/FastBridgeV2.Src.Base.t.sol - Added deprecated function test_nonce() that returns zero and verifies the nonce of fastBridge.
packages/contracts-rfq/test/FastBridgeV2.Src.t.sol - Added assertions in multiple test functions to verify correct incrementing of senderNonces for users A and B during bridge operations.

Possibly related PRs

Suggested labels

size/m, needs-go-generate-services/rfq, Sol, Typescript

Suggested reviewers

  • parodime
  • trajan0x

Poem

In the meadow where bunnies hop,
A nonce change made our hearts stop!
With senderNonces now in play,
Secure transactions lead the way.
Hopping high, we cheer with glee,
For safer bridges, wild and free! 🐇✨


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

Deploying sanguine-fe with  Cloudflare Pages  Cloudflare Pages

Latest commit: 0cb26c4
Status: ✅  Deploy successful!
Preview URL: https://c0ba66dc.sanguine-fe.pages.dev
Branch Preview URL: https://feat-fbv2-sendernonce2.sanguine-fe.pages.dev

View logs

Copy link

codecov bot commented Oct 2, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.74960%. Comparing base (8f1899d) to head (0cb26c4).
Report is 4 commits behind head on master.

Additional details and impacted files
@@                 Coverage Diff                 @@
##              master       #3214         +/-   ##
===================================================
+ Coverage   90.56974%   90.74960%   +0.17986%     
===================================================
  Files             54          60          +6     
  Lines           1018        1254        +236     
  Branches          82         150         +68     
===================================================
+ Hits             922        1138        +216     
- Misses            93         112         +19     
- Partials           3           4          +1     
Flag Coverage Δ
packages 90.56974% <ø> (ø)
solidity 91.52542% <ø> (?)

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

github-actions bot commented Oct 2, 2024

Changes to gas cost

Generated at commit: d19605b48f51ac1d8a38de9548c4249f4f941927, compared to commit: eb3db7ceb781feaa84f606869d9f9ffee5928cdf

🧾 Summary (50% most significant diffs)

Contract Method Avg (+/-) %
FastBridgeV2 bridge((uint32,address,address,address,address,uint256,uint256,bool,uint256))
bridge((uint32,address,address,address,address,uint256,uint256,bool,uint256),(address,int256,bytes))
bridgeProofs
claim(bytes,address)
dispute
+151 ❌
+145 ❌
+22 ❌
-110 ✅
-110 ✅
+0.18%
+0.18%
+3.53%
-0.21%
-0.35%

Full diff report 👇
Contract Deployment Cost (+/-) Method Min (+/-) % Avg (+/-) % Median (+/-) % Max (+/-) % # Calls (+/-)
FastBridgeV2 2,700,676 (+26,852) REFUNDER_ROLE
RELAYER_ROLE
bridge((uint32,address,address,address,address,uint256,uint256,bool,uint256))
bridge((uint32,address,address,address,address,uint256,uint256,bool,uint256),(address,int256,bytes))
bridgeProofs
bridgeStatuses
claim(bytes)
claim(bytes,address)
dispute
grantRole
prove(bytes,bytes32)
refund
relay(bytes)
relay(bytes,address)
setProtocolFeeRate
329 (+22)
329 (+22)
67,167 (+145)
69,326 (+145)
646 (+22)
616 (0)
42,754 (+22)
45,585 (-110)
31,174 (-110)
101,405 (+22)
35,089 (+22)
46,514 (+22)
65,485 (-109)
65,922 (-89)
47,421 (+22)
+7.17%
+7.17%
+0.22%
+0.21%
+3.53%
0.00%
+0.05%
-0.24%
-0.35%
+0.02%
+0.06%
+0.05%
-0.17%
-0.13%
+0.05%
329 (+22)
329 (+22)
82,165 (+151)
80,159 (+145)
646 (+22)
1,191 (+4)
50,288 (+22)
51,869 (-110)
31,174 (-110)
114,702 (+22)
35,116 (+22)
50,220 (+22)
71,380 (-109)
71,817 (-89)
47,421 (+22)
+7.17%
+7.17%
+0.18%
+0.18%
+3.53%
+0.34%
+0.04%
-0.21%
-0.35%
+0.02%
+0.06%
+0.04%
-0.15%
-0.12%
+0.05%
329 (+22)
329 (+22)
78,000 (+145)
80,159 (+145)
646 (+22)
616 (0)
50,297 (+22)
51,878 (-110)
31,174 (-110)
118,505 (+22)
35,119 (+22)
50,229 (+22)
71,380 (-109)
71,817 (-89)
47,421 (+22)
+7.17%
+7.17%
+0.19%
+0.18%
+3.53%
0.00%
+0.04%
-0.21%
-0.35%
+0.02%
+0.06%
+0.04%
-0.15%
-0.12%
+0.05%
329 (+22)
329 (+22)
105,933 (+145)
90,993 (+145)
646 (+22)
2,616 (0)
57,804 (+22)
58,135 (-110)
31,174 (-110)
118,505 (+22)
35,233 (+22)
53,908 (+22)
77,276 (-109)
77,713 (-89)
47,421 (+22)
+7.17%
+7.17%
+0.14%
+0.16%
+3.53%
0.00%
+0.04%
-0.19%
-0.35%
+0.02%
+0.06%
+0.04%
-0.14%
-0.11%
+0.05%
38 (+2)
76 (+4)
156 (+8)
4 (0)
8 (0)
264 (+12)
4 (0)
4 (0)
4 (0)
171 (+9)
42 (+2)
8 (0)
2 (0)
2 (0)
19 (+1)

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

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8f1899d and 6a913eb.

📒 Files selected for processing (3)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol (3 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Src.Base.t.sol (1 hunks)
  • packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (4 hunks)
🔇 Additional comments (7)
packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (6)

106-107: Excellent addition of nonce checks!

These assertions are crucial for verifying the correct implementation of sender-specific nonces. They ensure that:

  1. The nonce for userA is incremented after the bridge operation.
  2. The nonce for userB remains unchanged, as expected.

This helps prevent potential replay attacks and ensures proper transaction ordering per sender.


117-118: Great addition of nonce checks for different sender scenario!

These assertions are vital for verifying the correct behavior of sender-specific nonces when the caller is different from the sender. They confirm that:

  1. The nonce for userA (the sender specified in the parameters) is incremented after the bridge operation.
  2. The nonce for userB (the actual caller) remains unchanged.

This ensures that the nonce is correctly associated with the specified sender, not the transaction caller, maintaining proper transaction ordering and security.


133-134: Valuable nonce checks before ETH bridge operation!

These assertions are important for establishing the correct initial state before the ETH bridge operation. They verify that:

  1. The nonce for userA is 1, reflecting the previous token bridge operation.
  2. The nonce for userB is still 0, as expected.

This ensures that the test starts from a known, correct state, which is crucial for the validity of subsequent operations and assertions.


139-140: Crucial nonce checks after ETH bridge operation!

These assertions are essential for verifying the correct nonce behavior after multiple operations. They confirm that:

  1. The nonce for userA is incremented to 2, reflecting both the token and ETH bridge operations.
  2. The nonce for userB remains 0, as it hasn't performed any operations.

This ensures that the nonce is correctly incremented for each operation, maintaining proper transaction ordering and preventing potential replay attacks across different asset types.


148-149: Excellent nonce checks for ETH bridge with different sender!

These assertions and the modified bridge call are crucial for testing the correct behavior of sender-specific nonces in a complex scenario. They verify that:

  1. Initial state: userA's nonce is 1 (from token bridge), userB's nonce is 0.
  2. The ETH bridge is called by userB but with userA as the sender.
  3. Final state: userA's nonce is incremented to 2, userB's nonce remains 0.

This test ensures that the nonce is correctly associated with the specified sender (userA) rather than the transaction caller (userB), maintaining proper transaction ordering and security across different asset types and caller scenarios.

Also applies to: 153-156


164-165: Vital nonce checks for user-specific nonce initialization!

These assertions and the explicit nonce setting are crucial for testing the correct initialization and increment of user-specific nonces. They verify that:

  1. Initial state: userA's nonce is 1 (from previous token bridge), userB's nonce is 0.
  2. The ETH bridge transaction for userB is explicitly set with nonce 0.
  3. Final state: userA's nonce remains 1, userB's nonce is incremented to 1.

This test ensures that:

  • New users start with a nonce of 0.
  • The nonce is correctly incremented for a user's first transaction.
  • Other users' nonces remain unaffected.

This is essential for maintaining proper transaction ordering and security, especially when introducing new users to the system.

Also applies to: 174-175

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

31-32: Approved: Addition of sender-specific nonce tracking

The introduction of mapping(address => uint256) public senderNonces enhances the nonce management by tracking nonces per sender, reducing risks associated with global nonces and reorgs.

Comment on lines 98 to 101
function test_nonce() public view {
// deprecated. should always return zero in FbV2.
assertEq(fastBridge.nonce(), 0);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

⚠️ Potential issue

Update the test_nonce() function to reflect the new per-sender nonce implementation

The FastBridgeV2.sol contract now implements per-sender nonces using the senderNonces mapping. However, the test_nonce() function in FastBridgeV2.Src.Base.t.sol asserts that fastBridge.nonce() is always zero and is marked as deprecated. This discrepancy can lead to inaccurate test coverage and potential misunderstandings of the contract's functionality.

  • Action Items:
    1. Revise the test_nonce() function to test the senderNonces mapping correctly, ensuring that nonces increment per sender as intended.
    2. Remove or update the deprecated comment to clarify the current status and purpose of the test_nonce() function.
    3. Ensure all related tests are updated to align with the new nonce implementation to maintain consistent and reliable test coverage.
🔗 Analysis chain

Clarify the purpose of the test_nonce() function

The newly added test_nonce() function appears to be inconsistent with the PR objectives. While the PR aims to implement a per-sender nonce, this test function asserts that the nonce is always zero and is marked as deprecated. This raises several concerns:

  1. If the nonce is always zero, it doesn't align with the goal of implementing a per-sender nonce.
  2. The "deprecated" comment suggests this might be temporary or outdated code.
  3. The function name implies it's a test, but it's not using a testing framework assertion (e.g., assert instead of assertEq).

Consider the following actions:

  1. Clarify if this function is intended to be part of the final implementation or if it's a temporary placeholder.
  2. If it's meant to stay, update the function to properly test the new per-sender nonce behavior.
  3. If it's temporary, consider removing it or adding a TODO comment explaining its future purpose.

To better understand the context, let's check for other nonce-related implementations:

This will help us verify if the nonce implementation has been updated elsewhere in the contract.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for nonce-related implementations in the FastBridgeV2 contract
rg --type solidity -i "nonce" packages/contracts-rfq/src/FastBridgeV2.sol

Length of output: 106


Script:

#!/bin/bash
# Search for nonce-related implementations in the FastBridgeV2 contract without specifying file type
rg -i "nonce" packages/contracts-rfq/src/FastBridgeV2.sol

Length of output: 141


Script:

#!/bin/bash
# Search for FastBridgeV2.sol in the entire repository
fd "FastBridgeV2\.sol" . -t f

Length of output: 147


Script:

#!/bin/bash
# Search for nonce-related implementations in FastBridgeV2.sol
rg -i "nonce" packages/contracts-rfq/contracts/FastBridgeV2.sol

Length of output: 360

@@ -158,7 +163,7 @@
originFeeAmount: originFeeAmount,
sendChainGas: params.sendChainGas,
deadline: params.deadline,
nonce: nonce++, // increment nonce on every bridge
nonce: senderNonces[params.sender]++, // increment nonce on every bridge
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 off-by-one error due to postfix increment operator

The use of the postfix increment operator senderNonces[params.sender]++ assigns the current nonce value and then increments it. This means the nonce included in the request is the pre-incremented value. If the intention is to include the incremented nonce value, consider using the prefix increment operator ++senderNonces[params.sender] to avoid potential off-by-one errors.

Suggested change:

-                    nonce: senderNonces[params.sender]++, // increment nonce on every bridge
+                    nonce: ++senderNonces[params.sender], // increment nonce on every bridge
📝 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
nonce: senderNonces[params.sender]++, // increment nonce on every bridge
nonce: ++senderNonces[params.sender], // increment nonce on every bridge

Comment on lines 115 to 120
/// @notice This function is deprecated and should not be used.
/// @dev Replaced by senderNonces
function nonce() external pure returns (uint256) {
return 0;
}

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

Consider modifying or removing the deprecated nonce() function

The nonce() function is deprecated and currently returns 0, which might lead to confusion or unintended behavior if external callers rely on its previous functionality. Consider either removing the function or updating it to revert with a clear deprecation message to prevent misuse.

Suggested change:

function nonce() external pure returns (uint256) {
-    return 0;
+    revert("nonce() is deprecated and should not be used.");
}
📝 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
/// @notice This function is deprecated and should not be used.
/// @dev Replaced by senderNonces
function nonce() external pure returns (uint256) {
return 0;
}
/// @notice This function is deprecated and should not be used.
/// @dev Replaced by senderNonces
function nonce() external pure returns (uint256) {
revert("nonce() is deprecated and should not be used.");
}

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

31-36: Improved nonce management with per-sender tracking

The introduction of senderNonces mapping enhances security by preventing potential replay attacks across different senders. The deprecated nonce variable is correctly handled.

Consider adding a comment explaining why the deprecated nonce is kept as an immutable constant.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 15ca0de and 0cb26c4.

📒 Files selected for processing (2)
  • packages/contracts-rfq/.gitignore (1 hunks)
  • packages/contracts-rfq/contracts/FastBridgeV2.sol (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/contracts-rfq/.gitignore
🔇 Additional comments (3)
packages/contracts-rfq/contracts/FastBridgeV2.sol (3)

163-163: Nonce increment implementation is correct

The use of senderNonces[params.sender]++ is appropriate here. It assigns the current nonce to the transaction and then increments it for the next use, which is the desired behavior for nonce management.

Regarding the previous comment about a potential off-by-one error: The current implementation is correct. Using the postfix increment operator ensures that each transaction gets a unique, sequential nonce starting from the initial value (likely 0). This approach is standard in nonce management systems.


Line range hint 1-1: Summary of nonce management changes

The implementation of per-sender nonces in the FastBridgeV2 contract effectively addresses the PR objectives. The new system reduces the risk of reorgs leading to different nonces being used, enhancing the overall security of the bridge transactions.

Key points:

  1. The senderNonces mapping provides unique nonce tracking per sender.
  2. The bridge function correctly implements the new nonce management system.
  3. The old nonce variable is properly deprecated.

These changes align well with the goal of improving nonce management reliability in the system.


Line range hint 1-1: Verify the status of the deprecated nonce() function

The previously mentioned deprecated nonce() function is not visible in the provided code snippet. Please confirm if this function has been removed or modified as suggested in the previous review.

If the function still exists unchanged, consider implementing the suggested modification to prevent potential misuse:

function nonce() external pure returns (uint256) {
    revert("nonce() is deprecated and should not be used.");
}
✅ Verification successful

Nonce() Function Removal Verified

The deprecated nonce() function is no longer present in packages/contracts-rfq/contracts/FastBridgeV2.sol. Current references to nonce pertain to state variables and do not include the deprecated function.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for the nonce() function in the contract
rg --type solidity 'function\s+nonce\s*\(\s*\)\s*external' packages/contracts-rfq/contracts/FastBridgeV2.sol

Length of output: 143


Script:

#!/bin/bash
# Search for the nonce() function in the contract without specifying file type
rg 'function\s+nonce\s*\(\s*\)\s*external' packages/contracts-rfq/contracts/FastBridgeV2.sol

Length of output: 94


Script:

#!/bin/bash
# Search for any nonce() function definitions in the contract
ast-grep --lang solidity 'function nonce($_) { $$$ }' packages/contracts-rfq/contracts/FastBridgeV2.sol

# Search for any references or comments mentioning nonce in the contract
rg 'nonce' packages/contracts-rfq/contracts/FastBridgeV2.sol -A 2

Length of output: 797

Copy link
Collaborator

@ChiTimesChi ChiTimesChi left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link

codecov bot commented Oct 2, 2024

Bundle Report

Bundle size has no change ✅

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.

2 participants