-
Notifications
You must be signed in to change notification settings - Fork 32
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
status/proof mapping packing [SLT-186] #3173
Conversation
WalkthroughThe changes in this pull request focus on the Changes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
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? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
Outside diff range and nitpick comments (2)
packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (2)
312-314
: LGTM: bridgeProofs access updated correctly.The
bridgeProofs
access has been properly updated to use a struct-like syntax, which is consistent with the PR objectives of consolidating mappings. This change improves the code structure and readability.Consider using destructuring assignment for better readability:
-(uint96 timestamp, address relayer) = (fastBridge.bridgeProofs(txId).timestamp, fastBridge.bridgeProofs(txId).relayer); +var (timestamp, relayer) = (fastBridge.bridgeProofs(txId).timestamp, fastBridge.bridgeProofs(txId).relayer);
326-328
: LGTM: bridgeProofs access updated correctly for eth test.The
bridgeProofs
access has been properly updated to use a struct-like syntax in the eth test, which is consistent with the previous update for token tests and the PR objectives of consolidating mappings.Consider using destructuring assignment for better readability:
-(uint96 timestamp, address relayer) = (fastBridge.bridgeProofs(txId).timestamp, fastBridge.bridgeProofs(txId).relayer); +var (timestamp, relayer) = (fastBridge.bridgeProofs(txId).timestamp, fastBridge.bridgeProofs(txId).relayer);
Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Files selected for processing (4)
- packages/contracts-rfq/contracts/FastBridgeV2.sol (9 hunks)
- packages/contracts-rfq/contracts/interfaces/IFastBridgeV2.sol (1 hunks)
- packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (30 hunks)
- packages/contracts-rfq/test/FastBridgeV2.t.sol (1 hunks)
Additional comments not posted (24)
packages/contracts-rfq/test/FastBridgeV2.t.sol (1)
5-5
: Approve new import, but verify its usageThe addition of the
IFastBridgeV2
import is appropriate, likely reflecting updates to the FastBridge contract. However, I noticed that the test file doesn't explicitly use this new interface yet.To ensure proper test coverage for the new interface:
- Verify if any test cases need updating to use
IFastBridgeV2
.- Check if new test cases are required for any new functionality in
IFastBridgeV2
.Run the following script to check for usage of
IFastBridgeV2
in this test file:packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (18)
17-17
: LGTM: Import statement updated correctly.The addition of
IFastBridgeV2
to the import statement is consistent with the changes in the contract, allowing the use ofIFastBridgeV2.BridgeStatus
instead ofFastBridgeV2.BridgeStatus
.
170-172
: LGTM: assertEq function signature updated correctly.The
assertEq
function signature has been properly updated to useIFastBridgeV2.BridgeStatus
instead ofFastBridgeV2.BridgeStatus
. This change is consistent with the updated import statement and ensures that the test cases use the correctBridgeStatus
enum from the interface.
186-186
: LGTM: assertEq call updated correctly.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.REQUESTED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum.
194-194
: LGTM: assertEq call updated correctly.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.REQUESTED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum.
211-211
: LGTM: assertEq call updated correctly for eth test.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.REQUESTED
in the eth test. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for eth transactions.
221-221
: LGTM: assertEq call updated correctly for eth test.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.REQUESTED
in the eth test. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for eth transactions.
236-236
: LGTM: assertEq call updated correctly for user-specific nonce test.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.REQUESTED
in the user-specific nonce test. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for user-specific nonce transactions.
385-385
: LGTM: assertEq call updated correctly for claim token test.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for claimed transactions.
397-397
: LGTM: assertEq call updated correctly for permissionless claim token test.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for permissionless claimed transactions.
409-409
: LGTM: assertEq call updated correctly for permissionless claim token test with zero address.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for permissionless claimed transactions with zero address.
420-420
: LGTM: assertEq call updated correctly for claim token test with different address.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for claimed transactions with a different address.
432-432
: LGTM: assertEq call updated correctly for claim token test with long delay.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for claimed transactions with a long delay.
451-451
: LGTM: assertEq call updated correctly for claim eth test.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for claimed eth transactions.
464-464
: LGTM: assertEq call updated correctly for permissionless claim eth test.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for permissionless claimed eth transactions.
477-477
: LGTM: assertEq call updated correctly for permissionless claim eth test with zero address.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for permissionless claimed eth transactions with zero address.
489-489
: LGTM: assertEq call updated correctly for claim eth test with different address.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for claimed eth transactions with a different address.
501-501
: LGTM: assertEq call updated correctly for claim eth test with long delay.The
assertEq
call has been properly updated to useIFastBridgeV2.BridgeStatus.RELAYER_CLAIMED
. This change is consistent with the previous updates and ensures that the test case checks for the correct bridge status using the interface enum for claimed eth transactions with a long delay.
581-581
: LGTM: assertEq calls updated correctly for dispute tests.The
assertEq
calls have been properly updated to useIFastBridgeV2.BridgeStatus.REQUESTED
in the dispute tests. These changes are consistent with the previous updates and ensure that the test cases check for the correct bridge status using the interface enum for disputed transactions.Also applies to: 593-593, 605-605, 618-618
packages/contracts-rfq/contracts/interfaces/IFastBridgeV2.sol (2)
43-46
:bridgeStatuses
function correctly provides bridge transaction statusThe
bridgeStatuses
function is appropriately defined to return theBridgeStatus
for a giventransactionId
. This matches the intended functionality and complies with interface design.
48-51
:bridgeProofs
function correctly returns proof detailsThe
bridgeProofs
function is correctly defined to return the timestamp and relayer address associated with a bridge transaction. This aligns with the intended interface functionality.packages/contracts-rfq/contracts/FastBridgeV2.sol (3)
225-225
: Consistent Status Verification in Claim FunctionIn the
claim
function, you check if the status isRELAYER_PROVED
. Ensure that no other statuses (e.g.,REFUNDED
,DISPUTED
) could lead to unintended access to this function.
253-254
: Ensure Safe Time Calculations in Dispute FunctionIn the
dispute
function, the_timeSince
calculation might be susceptible to unexpected behavior if block timestamps are manipulated. Ensure that the function is secure against such scenarios.
257-258
: Confirm Complete Reset of Proof DataWhen calling
delete bridgeTxDetails[transactionId].proof;
, verify that all fields within theBridgeProof
struct are reset to their default values, and that no residual data remains.
struct BridgeTxDetails { | ||
BridgeStatus status; | ||
BridgeProof proof; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ensure BridgeProof
type is properly defined or imported
The BridgeProof
type used in the BridgeTxDetails
struct is not defined within this interface. Please verify that BridgeProof
is properly defined or imported from another contract or interface to prevent compilation errors.
function bridgeStatuses(bytes32 transactionId) public view returns (BridgeStatus status) | ||
{ | ||
return bridgeTxDetails[transactionId].status; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimize Getter Function Return Type
In the bridgeStatuses
function, you're returning a BridgeStatus
enum. While enums are convenient, returning them can be less gas-efficient. Consider returning a uint8
instead, which represents the underlying value of the enum and reduces gas consumption.
Consider this change:
-function bridgeStatuses(bytes32 transactionId) public view returns (BridgeStatus status)
+function bridgeStatuses(bytes32 transactionId) public view returns (uint8 status)
{
- return bridgeTxDetails[transactionId].status;
+ return uint8(bridgeTxDetails[transactionId].status);
}
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.
function bridgeStatuses(bytes32 transactionId) public view returns (BridgeStatus status) | |
{ | |
return bridgeTxDetails[transactionId].status; | |
} | |
function bridgeStatuses(bytes32 transactionId) public view returns (uint8 status) | |
{ | |
return uint8(bridgeTxDetails[transactionId].status); | |
} |
if (bridgeTxDetails[transactionId].status != BridgeStatus.RELAYER_PROVED) revert StatusIncorrect(); | ||
BridgeProof memory proof = bridgeTxDetails[transactionId].proof; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for Uninitialized Proof Before Access
When accessing bridgeTxDetails[transactionId].proof
, ensure that the proof exists to prevent accessing uninitialized memory, which could lead to incorrect data retrieval.
Add a check for proof initialization:
BridgeProof memory proof = bridgeTxDetails[transactionId].proof;
+if (proof.relayer == address(0)) revert ProofNotInitialized();
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.
if (bridgeTxDetails[transactionId].status != BridgeStatus.RELAYER_PROVED) revert StatusIncorrect(); | |
BridgeProof memory proof = bridgeTxDetails[transactionId].proof; | |
if (bridgeTxDetails[transactionId].status != BridgeStatus.RELAYER_PROVED) revert StatusIncorrect(); | |
BridgeProof memory proof = bridgeTxDetails[transactionId].proof; | |
if (proof.relayer == address(0)) revert ProofNotInitialized(); |
function bridgeProofs(bytes32 transactionId) public view returns (BridgeProof memory proof) | ||
{ | ||
return bridgeTxDetails[transactionId].proof; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid Returning Structs Directly from Public Functions
The bridgeProofs
function returns a BridgeProof
struct. Returning structs can be expensive in terms of gas and may expose internal implementation details. Instead, consider returning individual fields of the struct.
Refactor the function to return individual fields:
-function bridgeProofs(bytes32 transactionId) public view returns (BridgeProof memory proof)
+function bridgeProofs(bytes32 transactionId) public view returns (uint96 timestamp, address relayer)
{
- return bridgeTxDetails[transactionId].proof;
+ BridgeProof memory proof = bridgeTxDetails[transactionId].proof;
+ return (proof.timestamp, proof.relayer);
}
Committable suggestion was skipped due to low confidence.
if (bridgeTxDetails[transactionId].status != BridgeStatus.REQUESTED) revert StatusIncorrect(); | ||
bridgeTxDetails[transactionId].status = BridgeStatus.RELAYER_PROVED; | ||
bridgeTxDetails[transactionId].proof = BridgeProof({timestamp: uint96(block.timestamp), relayer: relayer}); // overflow ok |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tip
Codebase Verification
❗ Unexpected Status Transition Detected
The status transition from REQUESTED
to REFUNDED
is not defined in the expected state machine (REQUESTED
→ RELAYER_PROVED
→ RELAYER_CLAIMED
). Please review the state transitions to ensure they adhere to the intended workflow.
Analysis chain
Confirm Proper Status Transition and Proof Assignment
Before updating the status to RELAYER_PROVED
and assigning the proof, ensure that the transition from REQUESTED
to RELAYER_PROVED
is valid according to your state machine. This prevents invalid status transitions.
Run the following script to verify status transitions:
Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that all status transitions in the code follow the defined state machine.
# Expected statuses in order: REQUESTED -> RELAYER_PROVED -> RELAYER_CLAIMED
# Search for all status updates
rg --type solidity 'bridgeTxDetails\[.*\].status = BridgeStatus\.\w+' -A 2
Length of output: 109
Script:
#!/bin/bash
# Description: Verify that all status transitions in the Solidity code follow the defined state machine.
# Expected statuses in order: REQUESTED -> RELAYER_PROVED -> RELAYER_CLAIMED
# Search for all status updates in .sol files
rg --glob '*.sol' 'bridgeTxDetails\[.*\].status\s*=\s*BridgeStatus\.\w+' -A 2
Length of output: 1552
Deploying sanguine-fe with Cloudflare Pages
|
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #3173 +/- ##
===================================================
- Coverage 40.97804% 38.45965% -2.51839%
===================================================
Files 459 424 -35
Lines 25643 24462 -1181
Branches 343 148 -195
===================================================
- Hits 10508 9408 -1100
+ Misses 14383 14314 -69
+ Partials 752 740 -12
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
struct BridgeTxDetails { | ||
BridgeStatus status; | ||
BridgeProof proof; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will not have a desired effect of saving the gas on reads and writes, as the internal composition of the struct takes more than a single storage slot (256 bits). We don't export a gas report as of now, but in this case it's possible to generate using forge t --mc FastBridgeV2SrcTest --nmt revert --gas-report
.
- Using
FastBridgeV2SrcTest
test contract gives us the overview for the source chain-related functions --nmt revert
excludes test functions having a word "revert" in the name, which makes the report more useful (revert cases in general consume less gas, and thus need to be filtered)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To gain the performance in gas consumption, the BridgeTxDetails
needs to fit within 256 bits:
BridgeStatus
enum is equivalent touint8
address relayer
takes 160 bits- which leaves up to 88 bits for the proof's timestamp
This is an opportunity to follow the suit of #3170 and also store the block number, when the prove happened. This could be useful for some of the Relayer implementations. This will require using up to 88 bits for both block number and timestamp, which is more than enough for practical purposes.
There was a problem hiding this 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
📒 Files selected for processing (3)
- packages/contracts-rfq/contracts/FastBridgeV2.sol (9 hunks)
- packages/contracts-rfq/contracts/interfaces/IFastBridgeV2.sol (1 hunks)
- packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (30 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/contracts-rfq/contracts/interfaces/IFastBridgeV2.sol
- packages/contracts-rfq/test/FastBridgeV2.Src.t.sol
🔇 Additional comments not posted (5)
packages/contracts-rfq/contracts/FastBridgeV2.sol (5)
187-190
: LGTM: Proper status check and proof updateThe changes in the
prove
function correctly update the status and proof details in thebridgeTxDetails
mapping. The status check ensures that only transactions in theREQUESTED
state can be proved, maintaining the expected state machine flow.
209-210
: LGTM: Correct status check and proof retrievalThe
canClaim
function has been properly updated to use the newbridgeTxDetails
mapping. It correctly checks the status and retrieves the proof, maintaining the existing logic while using the new data structure.
226-226
: LGTM: Proper status handling and proof retrieval in claim functionThe
claim
function has been correctly updated to use the newbridgeTxDetails
mapping. It properly checks and updates the transaction status, and correctly retrieves the proof details. The changes maintain the existing logic while utilizing the new data structure effectively.Also applies to: 228-228, 239-239
27-27
: 🛠️ Refactor suggestionConsider changing
bridgeTxDetails
visibility to privateThe
bridgeTxDetails
mapping is declared as public, which allows direct access to the internal data structure. To improve encapsulation and control access to this data, consider changing the visibility to private and using the newly added getter functionsbridgeStatuses
andbridgeProofs
for external access.Apply this change:
- mapping(bytes32 => BridgeTxDetails) public bridgeTxDetails; + mapping(bytes32 => BridgeTxDetails) private bridgeTxDetails;Likely invalid or redundant comment.
113-113
:⚠️ Potential issueEnsure transaction ID uniqueness before setting status
When setting the status to
REQUESTED
, it's important to verify that thetransactionId
is unique and hasn't been used in a previous transaction. This prevents overwriting existing transaction details.Consider adding a check:
+if (bridgeTxDetails[transactionId].status != BridgeStatus.NONE) revert TransactionAlreadyExists(); bridgeTxDetails[transactionId].status = BridgeStatus.REQUESTED;
Don't forget to define the
TransactionAlreadyExists
error in yourErrors.sol
file.Likely invalid or redundant comment.
There was a problem hiding this 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 (5)
packages/contracts-rfq/test/FastBridgeV2.Parity.t.sol (3)
15-28
: LGTM! Consider adding a comment for clarity.The
assertCorrectProof
function is well-implemented and consistent with the stated purpose. It correctly retrieves and verifies the proof details.Consider adding a brief comment explaining the purpose of this function, e.g.:
/// @dev Verifies that the proof for a given transaction matches the expected timestamp and relayer
Line range hint
30-38
: Skipped tests are well-documented. Consider future test updates.The decision to skip
test_failedRelayNotRelayer
andtest_failedClaimNotRelayer
is well-justified and clearly explained in the comments.While skipping these tests is appropriate for now, consider replacing them with new tests that verify the updated permission model in FastBridgeV2. This will ensure that the new behavior is properly tested.
Line range hint
40-55
: Modified test correctly reflects updated permission model.The
test_failedClaimNotOldRelayer
function has been appropriately updated to align with the new permission model in FastBridgeV2.To improve clarity, consider renaming the test function to better reflect its current purpose, e.g.,
test_failedClaimNotProvenRelayer
. This would more accurately describe what the test is now verifying.packages/contracts-rfq/test/FastBridge.t.sol (2)
1725-1725
: Good use ofassertCorrectProof
in dispute test!The replacement of direct assertions with
assertCorrectProof
in this dispute test case maintains consistency with other changes and improves readability.Consider adding a comment or updating the test name to clarify that this assertion is checking for reset proof details after a successful dispute. For example:
- assertCorrectProof(transactionId, 0, address(0)); + // Assert that the proof details are reset after a successful dispute + assertCorrectProof(transactionId, 0, address(0));
1749-1749
: Consistent use ofassertCorrectProof
in overflow dispute test!The use of
assertCorrectProof
in this overflow dispute test case maintains consistency with other changes and improves the overall structure of the test suite.Similar to the previous suggestion, consider adding a comment to clarify that this assertion is checking for reset proof details after a successful dispute in an overflow scenario. For example:
- assertCorrectProof(transactionId, 0, address(0)); + // Assert that the proof details are reset after a successful dispute, even in an overflow scenario + assertCorrectProof(transactionId, 0, address(0));
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (2)
- packages/contracts-rfq/test/FastBridge.t.sol (7 hunks)
- packages/contracts-rfq/test/FastBridgeV2.Parity.t.sol (1 hunks)
🔇 Additional comments not posted (5)
packages/contracts-rfq/test/FastBridge.t.sol (5)
55-66
: Great addition of theassertCorrectProof
helper function!This new function encapsulates the logic for asserting the correctness of bridge transaction proofs, which will help reduce code duplication and improve the maintainability of the test suite. It's a good practice to create such helper functions for commonly used assertions.
1366-1366
: Good use of the newassertCorrectProof
function!Replacing the direct assertions with a call to
assertCorrectProof
improves the readability and consistency of the test case. This change will make it easier to maintain and update these assertions in the future if needed.
1398-1398
: Consistent use ofassertCorrectProof
in overflow test!The replacement of direct assertions with
assertCorrectProof
in this overflow test case maintains consistency with other similar changes. This consistency improves the overall structure and readability of the test suite.
1427-1427
: Consistent application ofassertCorrectProof
in delay test!The use of
assertCorrectProof
in this test case with a huge delay maintains the consistent structure across different scenarios. This consistency in test structure will make it easier for developers to understand and maintain the test suite in the future.
Line range hint
1-1749
: Overall improvement in test structure and readability!The introduction of the
assertCorrectProof
helper function and its consistent application across various test cases significantly enhances the structure and readability of the test suite. This refactoring reduces code duplication and improves maintainability, making it easier for developers to understand and update the tests in the future.The consistent use of this new function across different scenarios (normal operations, overflow conditions, and disputes) ensures a uniform approach to asserting proof correctness throughout the test suite.
These changes represent a positive step in improving the quality and maintainability of the test code for the FastBridge contract.
Bundle ReportChanges will decrease total bundle size by 157.85kB (-0.44%) ⬇️. This is within the configured threshold ✅ Detailed changes
|
There was a problem hiding this 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
🧹 Outside diff range and nitpick comments (2)
packages/contracts-rfq/contracts/FastBridgeV2.sol (2)
Line range hint
225-249
: Emit event for status change toRELAYER_CLAIMED
After updating the status to
RELAYER_CLAIMED
, consider emitting an event to log this state change. This improves transparency and facilitates off-chain tracking of transaction statuses.Add an event emission:
_thisBridgeTxDetails.status = BridgeStatus.RELAYER_CLAIMED; +emit BridgeStatusUpdated(transactionId, BridgeStatus.RELAYER_CLAIMED);
Ensure you've defined the
BridgeStatusUpdated
event as suggested in a previous comment. This addition would enhance the contract's observability and make it easier to track the complete lifecycle of bridge transactions.
Line range hint
273-285
: Emit event for status change toREFUNDED
After updating the status to
REFUNDED
, it would be beneficial to emit an event logging this state change. This improves transparency and aids in off-chain tracking of transaction statuses.Add an event emission:
bridgeTxDetails[transactionId].status = BridgeStatus.REFUNDED; +emit BridgeStatusUpdated(transactionId, BridgeStatus.REFUNDED);
Ensure you've defined the
BridgeStatusUpdated
event as suggested in previous comments. This addition would further enhance the contract's observability and provide a complete picture of the bridge transaction lifecycle.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (2)
- packages/contracts-rfq/contracts/FastBridgeV2.sol (8 hunks)
- packages/contracts-rfq/contracts/interfaces/IFastBridgeV2.sol (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/contracts-rfq/contracts/interfaces/IFastBridgeV2.sol
🔇 Additional comments not posted (5)
packages/contracts-rfq/contracts/FastBridgeV2.sol (5)
196-203
: LGTM: Efficient timestamp calculationThe
_timeSince
function has been optimized to useuint40
for timestamp calculations, which aligns well with the storage optimization inBridgeTxDetails
. The unchecked block correctly handles potential overflow scenarios. This implementation is both gas-efficient and functionally correct.
209-212
: LGTM: Correct usage of consolidated mappingThe
canClaim
function has been successfully updated to use the newbridgeTxDetails
mapping. It correctly accesses the relevant fields from theBridgeTxDetails
struct while maintaining the original logic. This change aligns well with the optimization goals of the PR.
36-38
: 🛠️ Refactor suggestionOptimize
bridgeStatuses
return type for gas efficiencyThe
bridgeStatuses
function returns aBridgeStatus
enum. While enums are convenient for readability, returning them can be less gas-efficient. Consider returning auint8
instead, which represents the underlying value of the enum.-function bridgeStatuses(bytes32 transactionId) public view returns (BridgeStatus status) { +function bridgeStatuses(bytes32 transactionId) public view returns (uint8 status) { - return bridgeTxDetails[transactionId].status; + return uint8(bridgeTxDetails[transactionId].status); }This change would maintain backwards compatibility while potentially reducing gas costs for callers.
Likely invalid or redundant comment.
27-27
: 🛠️ Refactor suggestionConsider making
bridgeTxDetails
mapping privateWhile the new
bridgeTxDetails
mapping effectively consolidatesbridgeStatuses
andbridgeProofs
, making it public allows direct access to the entireBridgeTxDetails
struct. Consider making this mapping private and relying on specific getter functions for better encapsulation and potential gas savings.- mapping(bytes32 => BridgeTxDetails) public bridgeTxDetails; + mapping(bytes32 => BridgeTxDetails) private bridgeTxDetails;This change would align with the principle of minimal exposure and could potentially save gas by preventing unnecessary SLOAD operations when only specific fields are needed.
Likely invalid or redundant comment.
111-111
:⚠️ Potential issueAdd check for existing transactions before setting status
When setting the status to
REQUESTED
, it's important to ensure that thetransactionId
doesn't already exist in thebridgeTxDetails
mapping. This prevents accidentally overwriting an existing transaction.Consider adding a check:
+ if (bridgeTxDetails[transactionId].status != BridgeStatus.NONE) revert TransactionAlreadyExists(); bridgeTxDetails[transactionId].status = BridgeStatus.REQUESTED;
This addition would prevent potential issues with duplicate transaction IDs and improve the contract's robustness.
Likely invalid or redundant comment.
if (bridgeTxDetails[transactionId].status != BridgeStatus.REQUESTED) revert StatusIncorrect(); | ||
BridgeTxDetails storage _thisBridgeTxDetails = bridgeTxDetails[transactionId]; | ||
_thisBridgeTxDetails.status = BridgeStatus.RELAYER_PROVED; | ||
_thisBridgeTxDetails.proofBlockTimestamp = uint40(block.timestamp); | ||
_thisBridgeTxDetails.proofBlockNumber = uint48(block.number); | ||
_thisBridgeTxDetails.proofRelayer = relayer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Emit event for status change to RELAYER_PROVED
After updating the status to RELAYER_PROVED
, consider emitting an event to log this state change. This aids in transparency and off-chain tracking of transaction statuses.
Add an event emission:
_thisBridgeTxDetails.status = BridgeStatus.RELAYER_PROVED;
_thisBridgeTxDetails.proofBlockTimestamp = uint40(block.timestamp);
_thisBridgeTxDetails.proofBlockNumber = uint48(block.number);
_thisBridgeTxDetails.proofRelayer = relayer;
+emit BridgeStatusUpdated(transactionId, BridgeStatus.RELAYER_PROVED);
Don't forget to define the event:
event BridgeStatusUpdated(bytes32 indexed transactionId, BridgeStatus status);
This addition would improve the contract's observability and make it easier to track the lifecycle of bridge transactions.
function bridgeProofs(bytes32 transactionId) public view returns (BridgeProof memory) { | ||
BridgeTxDetails storage _thisBridgeTxDetails = bridgeTxDetails[transactionId]; | ||
return BridgeProof(_thisBridgeTxDetails.proofBlockTimestamp, _thisBridgeTxDetails.proofRelayer); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider returning individual values instead of BridgeProof
struct
The bridgeProofs
function returns a BridgeProof
struct. Returning structs can be gas-inefficient and may expose internal implementation details. Consider returning individual fields of the struct instead.
-function bridgeProofs(bytes32 transactionId) public view returns (BridgeProof memory) {
+function bridgeProofs(bytes32 transactionId) public view returns (uint40 timestamp, address relayer) {
BridgeTxDetails storage _thisBridgeTxDetails = bridgeTxDetails[transactionId];
- return BridgeProof(_thisBridgeTxDetails.proofBlockTimestamp, _thisBridgeTxDetails.proofRelayer);
+ return (_thisBridgeTxDetails.proofBlockTimestamp, _thisBridgeTxDetails.proofRelayer);
}
This change would maintain backwards compatibility while potentially reducing gas costs and limiting exposure of internal structures.
📝 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.
function bridgeProofs(bytes32 transactionId) public view returns (BridgeProof memory) { | |
BridgeTxDetails storage _thisBridgeTxDetails = bridgeTxDetails[transactionId]; | |
return BridgeProof(_thisBridgeTxDetails.proofBlockTimestamp, _thisBridgeTxDetails.proofRelayer); | |
} | |
function bridgeProofs(bytes32 transactionId) public view returns (uint40 timestamp, address relayer) { | |
BridgeTxDetails storage _thisBridgeTxDetails = bridgeTxDetails[transactionId]; | |
return (_thisBridgeTxDetails.proofBlockTimestamp, _thisBridgeTxDetails.proofRelayer); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a fan of storage
approach (see the comments) + needs merge conflicts to be resolved.
There was a problem hiding this 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/interfaces/IFastBridgeV2.sol (1)
7-13
: Consider renaming theNULL
state for improved clarityThe
BridgeStatus
enum provides a clear representation of the possible states of a bridge transaction. However, theNULL
state could be renamed to improve clarity and avoid potential confusion with null values in other programming contexts.Consider renaming
NULL
to a more descriptive term such asNOT_INITIATED
orUNINITIALIZED
. For example:enum BridgeStatus { - NULL, // doesn't exist yet + NOT_INITIATED, // doesn't exist yet REQUESTED, RELAYER_PROVED, RELAYER_CLAIMED, REFUNDED }The rest of the enum looks good and follows a logical order of states for a bridge transaction.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (4)
- packages/contracts-rfq/contracts/FastBridgeV2.sol (8 hunks)
- packages/contracts-rfq/contracts/interfaces/IFastBridgeV2.sol (2 hunks)
- packages/contracts-rfq/test/FastBridgeV2.Parity.t.sol (1 hunks)
- packages/contracts-rfq/test/FastBridgeV2.Src.t.sol (28 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/contracts-rfq/contracts/FastBridgeV2.sol
- packages/contracts-rfq/test/FastBridgeV2.Parity.t.sol
- packages/contracts-rfq/test/FastBridgeV2.Src.t.sol
🔇 Additional comments (1)
packages/contracts-rfq/contracts/interfaces/IFastBridgeV2.sol (1)
15-20
: Efficient struct packing for gas optimizationThe
BridgeTxDetails
struct is well-designed for gas efficiency:
- It uses smaller uint types (uint40 and uint48) for timestamp and block number, which are sufficient for their purposes.
- The struct is packed into a single 256-bit storage slot:
- BridgeStatus enum (8 bits)
- uint40 proofBlockTimestamp (40 bits)
- uint48 proofBlockNumber (48 bits)
- address proofRelayer (160 bits)
Total: 256 bitsThis efficient packing addresses the gas optimization concerns raised in previous comments and will lead to reduced gas costs for storage operations.
Description
A lot of functions are reading/writing from/to both
bridgeStatuses
andbridgeProofs
, wasting more gas than necessary.bridgeStatuses(bytes32)
andbridgeProofs(bytes32)
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Tests