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

refactor: separate NST deposit/withdrawal from LST deposit/withdrawal #96

Merged
merged 13 commits into from
Sep 25, 2024

Conversation

adu-web3
Copy link
Collaborator

@adu-web3 adu-web3 commented Sep 13, 2024

Description

closes: #65
closes: #3
closes: #57
closes: #77

To enable updating beacon chain balance by oracle module, we should send the validator pubkey to Exocore to be recorded. So we should separate NST(native staking token) message from LST message when doing deposit/withdrawal from client chain to Exocore

This PR involves relatively big refactoring to support adding more message types and message handlers, as well as making the code better organized. For reviewer's convenience, I would list the scope and list of tasks for this pr:

Scope

The refactoring mainly happens to:

  1. ClientGatewayLzReceiver: refactor the handleResponse function to simplify the process, since only withdrawal actions need response from Exocore after we remove the principal balances and reward balances from Vault
  2. ExocoreGateway: refactor the original requestXXX message handlers as handleXXX to remove redundant logics(though there are still some repeated logics) and add new message handlers to support NST deposit/withdrawal, and also remove the try/catch wrapper when calling precompiles, because:
    a. try/catch is actually not working since we cannot catch the revert caused by precompile
    b. precompiled contracts are not outside contracts and we can easily avoid revert happening by not returning errors for precompile handlers
  3. NativeRestakingController: encode validator's pubkey into the message when doing deposit/withdrawal for native restaking
  4. Vault and ExoCapsule: remove the principalBalances and rewardBalances states since we have decided to not storing them on client chain side and they are not used as constraints in any scenario like depoist/withdraw/delegate/undelegate
  5. ActionAttributes: use bitmap to represent each action's attributes and message length, so that it might be less error prone and more explicit
  6. IAssets and IDelegation precompiles: add new interfaces to support deposit/withdraw NST with validator's pubkey, and revise some function names to make them more concise

Targeted Tasks

  • send validator's pubkey to Exocore when doing NST(native staking token) deposit/withdrawal so that oracle module could update staker's balance based on validators list
  • remove principalBalances and rewardBalances from VaultStorage and ExoCapsuleStorage, and remove corresponding update functions from interfaces, vault/exocapsule implementations and even caller contracts(Bootstrap and ClientGatewayLzReceiver)
  • add ActionAttributes to represent action attributes as bitmaps and optimize the redundant functions
  • move all errors definitions to Errors.lib
  • update docs based on the refactoring
  • review Exocore precompiles implementations to conform to the interfaces

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced new components such as Bootstrap, ExoCapsule, and NativeRestakingController to enhance the Exocore system.
    • Added events for asset transfers and delegation requests, improving logging capabilities.
  • Bug Fixes

    • Updated error messages for improved clarity, including changes from "CapsuleNotExist" to "CapsuleDoesNotExist."
    • Enhanced error handling by centralizing definitions within the Errors library, providing clearer feedback for various scenarios.
  • Refactor

    • Streamlined internal logic for handling deposits, withdrawals, and delegation actions, improving maintainability and readability.
    • Removed outdated constants and replaced them with dynamic handling for message lengths.
  • Documentation

    • Updated documentation to reflect changes in error handling and event emissions for better clarity.

Copy link
Contributor

coderabbitai bot commented Sep 13, 2024

Walkthrough

The pull request introduces significant changes across multiple smart contract files, primarily focusing on restructuring action handling and enhancing error management. A new Bootstrap contract has been added, and existing contracts have been updated to streamline operations related to deposits, withdrawals, and delegation within the Exocore ecosystem. Event emissions and error handling have been refined for improved clarity.

Changes

Files Change Summary
docs/client-chain-contracts-design.md, src/core/ExocoreGateway.sol, src/libraries/Errors.sol, src/storage/BootstrapStorage.sol, src/storage/ClientChainGatewayStorage.sol, src/storage/ExocoreGatewayStorage.sol Introduced new components, updated error handling, and restructured event emissions for clarity and consistency.
docs/native_deposit_workflow.wsd Modified error message from "CapsuleNotExist" to "CapsuleDoesNotExist" for improved clarity.
src/storage/ExocoreGatewayStorage.sol Consolidated event emissions related to asset transfers and improved message validation logic.
test/foundry/unit/ClientChainGateway.t.sol Updated tests to reflect changes in error handling and action references for improved clarity.

Assessment against linked issues

Objective Addressed Explanation
View functions for querying ExoCapsules and validators (#65) No new view functions were added for querying.
Save LayerZero relaying fee by not sending response back (#3) The changes streamline response handling for deposits and delegation.
Optimize _handleResponse function using bit operations (#57) The changes do not directly address this optimization.
Remove unused states principalBalances and rewardBalances (#77) The unused states were not removed as part of this PR.

Possibly related PRs

Poem

🐇 In the meadow where the code does play,
A rabbit hops, with joy today!
Actions now dance in a clearer light,
Errors tamed, and logic feels right.
With every change, we leap and bound,
In the world of contracts, joy is found! 🌼


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 or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@adu-web3 adu-web3 marked this pull request as ready for review September 19, 2024 10:11
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: 21

Outside diff range and nitpick comments (8)
src/core/ClientChainGateway.sol (1)

18-18: Clarify the purpose of importing Action or remove the unused import.

The Action enum is imported from GatewayStorage.sol, but it is not used in the provided code changes. Unused imports can clutter the code and make it harder to maintain.

Please clarify the purpose of importing Action. If it is not used, consider removing the import:

-import {Action} from "../storage/GatewayStorage.sol";
src/core/NativeRestakingController.sol (1)

8-9: Nitpick: Remove the empty line between the import statements.

The empty line between the import statements is inconsistent with the rest of the file. Consider removing it to maintain consistent formatting.

-
 import {Action} from "../storage/GatewayStorage.sol";
test/foundry/DepositWithdrawPrinciple.t.sol (1)

90-90: Approve with a minor suggestion.

The LST deposit test function follows the expected workflow and validates the emitted events correctly. Consider adding a comment to explain the purpose of updating the lastlyUpdatedPrincipalBalance variable for better clarity.

Also applies to: 112-112, 119-128

test/foundry/unit/Bootstrap.t.sol (1)

Line range hint 1162-1184: Add assertions to verify the deposit success.

The test function test02_Deposit_Success tests the successful deposit scenario with a whitelisted token. However, it lacks assertions to verify that the deposit was indeed successful.

Consider adding assertions to check the following after the deposit:

  • The balance of the depositor should decrease by the deposited amount.
  • The total deposit amount for the depositor and token should increase by the deposited amount.
  • The vault's balance should increase by the deposited amount.
src/storage/GatewayStorage.sol (1)

7-21: Ensure consistent naming in the Action enum

While most enum values use the REQUEST_ prefix, the RESPOND action does not follow this pattern. For consistency, consider renaming RESPOND to REQUEST_RESPOND or RESPONSE to align with the naming convention.

test/mocks/AssetsMock.sol (2)

29-30: Improve error messages for clarity

Consider rephrasing the error messages to enhance clarity:

  • Line 29: "only support LST" → "only LST tokens are supported"
  • Line 30: "the token is not registered before" → "the token is not registered"

Apply this diff to update the error messages:

- require(bytes32(assetsAddress) != bytes32(bytes20(VIRTUAL_STAKED_ETH_ADDRESS)), "only support LST");
+ require(bytes32(assetsAddress) != bytes32(bytes20(VIRTUAL_STAKED_ETH_ADDRESS)), "only LST tokens are supported");

- require(isRegisteredToken[clientChainLzId][assetsAddress], "the token is not registered before");
+ require(isRegisteredToken[clientChainLzId][assetsAddress], "the token is not registered");

51-73: Add validation for opAmount in withdrawLST

To prevent zero or negative withdrawal amounts, add a check to ensure opAmount is greater than zero.

Apply this diff to include the validation:

 function withdrawLST(
     uint32 clientChainLzId,
     bytes calldata assetsAddress,
     bytes calldata withdrawer,
     uint256 opAmount
 ) external returns (bool success, uint256 latestAssetState) {
     require(assetsAddress.length == 32, "invalid asset address");
     require(withdrawer.length == 32, "invalid staker address");
+    require(opAmount > 0, "opAmount must be greater than zero");

     if (bytes32(assetsAddress) == bytes32(bytes20(VIRTUAL_STAKED_ETH_ADDRESS))) {
         return (false, 0);
     }
     if (!isRegisteredToken[clientChainLzId][assetsAddress]) {
         return (false, 0);
     }

     if (opAmount > principalBalances[clientChainLzId][assetsAddress][withdrawer]) {
         return (false, 0);
     }

     principalBalances[clientChainLzId][assetsAddress][withdrawer] -= opAmount;

     return (true, principalBalances[clientChainLzId][assetsAddress][withdrawer]);
 }
src/libraries/Errors.sol (1)

245-247: Parameter Naming: Rename selector_ to selector

In the error PrecompileCallFailed(bytes4 selector_, bytes reason);, the parameter name selector_ ends with an underscore. Unless there is a naming conflict, consider renaming it to selector for consistency with other parameter names.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 9b5e7e0 and 58832f0.

Files selected for processing (43)
  • script/11_SetPeers.s.sol (2 hunks)
  • script/13_DepositValidator.s.sol (2 hunks)
  • script/3_Setup.s.sol (2 hunks)
  • script/4_Deposit.s.sol (2 hunks)
  • script/5_Withdraw.s.sol (2 hunks)
  • script/TestPrecompileErrorFixed.s.sol (3 hunks)
  • script/TestPrecompileErrorFixed_Deploy.s.sol (1 hunks)
  • src/core/BaseRestakingController.sol (4 hunks)
  • src/core/Bootstrap.sol (4 hunks)
  • src/core/BootstrapLzReceiver.sol (3 hunks)
  • src/core/ClientChainGateway.sol (2 hunks)
  • src/core/ClientGatewayLzReceiver.sol (5 hunks)
  • src/core/ExoCapsule.sol (0 hunks)
  • src/core/ExocoreGateway.sol (5 hunks)
  • src/core/LSTRestakingController.sol (5 hunks)
  • src/core/NativeRestakingController.sol (4 hunks)
  • src/core/Vault.sol (0 hunks)
  • src/interfaces/IExoCapsule.sol (0 hunks)
  • src/interfaces/IVault.sol (0 hunks)
  • src/interfaces/precompiles/IAssets.sol (2 hunks)
  • src/interfaces/precompiles/IClaimReward.sol (1 hunks)
  • src/interfaces/precompiles/IDelegation.sol (4 hunks)
  • src/libraries/ActionAttributes.sol (1 hunks)
  • src/libraries/Errors.sol (6 hunks)
  • src/storage/BootstrapStorage.sol (3 hunks)
  • src/storage/ClientChainGatewayStorage.sol (3 hunks)
  • src/storage/ExoCapsuleStorage.sol (0 hunks)
  • src/storage/ExocoreGatewayStorage.sol (2 hunks)
  • src/storage/GatewayStorage.sol (2 hunks)
  • src/storage/VaultStorage.sol (0 hunks)
  • test/foundry/Delegation.t.sol (8 hunks)
  • test/foundry/DepositThenDelegateTo.t.sol (9 hunks)
  • test/foundry/DepositWithdrawPrinciple.t.sol (27 hunks)
  • test/foundry/ExocoreDeployer.t.sol (7 hunks)
  • test/foundry/WithdrawReward.t.sol (7 hunks)
  • test/foundry/unit/Bootstrap.t.sol (2 hunks)
  • test/foundry/unit/ClientChainGateway.t.sol (6 hunks)
  • test/foundry/unit/ExocoreGateway.t.sol (13 hunks)
  • test/mocks/AssetsMock.sol (2 hunks)
  • test/mocks/ClaimRewardMock.sol (1 hunks)
  • test/mocks/DelegationMock.sol (5 hunks)
  • test/mocks/ExocoreGatewayMock.sol (10 hunks)
  • test/mocks/PrecompileCallerMock.sol (1 hunks)
Files not reviewed due to no reviewable changes (6)
  • src/core/ExoCapsule.sol
  • src/core/Vault.sol
  • src/interfaces/IExoCapsule.sol
  • src/interfaces/IVault.sol
  • src/storage/ExoCapsuleStorage.sol
  • src/storage/VaultStorage.sol
Files skipped from review due to trivial changes (1)
  • src/interfaces/precompiles/IClaimReward.sol
Additional comments not posted (150)
test/mocks/ClaimRewardMock.sol (1)

7-12: LGTM! The parameter type change is a good optimization.

Changing the parameter types from bytes memory to bytes calldata for assetsAddress and withdrawer is a gas optimization technique in Solidity.

calldata allows read-only function parameters to be passed by reference directly from the call data, which is cheaper than copying them to memory. This can lead to gas savings when calling the function, especially for larger byte arrays.

Since the function logic and behavior remain unchanged, with the same validation checks and return values, this change has no negative impact and can be safely approved.

test/mocks/PrecompileCallerMock.sol (1)

15-15: Verify the existence and signature of the depositLST function.

This change in the mock contract suggests that the ASSETS_CONTRACT now has a depositLST function instead of depositTo. Please ensure that:

  1. The depositLST function exists in the ASSETS_CONTRACT interface (IAssets).
  2. The parameters passed to depositLST in this mock are correct and match its signature.

Run the following script to verify the existence and signature of depositLST:

Verification successful

Verification successful: depositLST function exists in IAssets interface

The depositLST function has been confirmed to exist in the IAssets interface (src/interfaces/precompiles/IAssets.sol) and is correctly used in the mock contract (test/mocks/PrecompileCallerMock.sol). This verifies that the change in the mock contract reflects a valid function in the interface.

However, please manually verify:

  1. The parameters of the depositLST function in src/interfaces/precompiles/IAssets.sol match those used in test/mocks/PrecompileCallerMock.sol.
  2. The implementation in test/mocks/AssetsMock.sol is consistent with the interface and mock usage.
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence and signature of the `depositLST` function in the `IAssets` interface.

# Test: Search for the function declaration. Expect: A match with the correct signature.
rg --type solidity -A 5 $'function\s+depositLST\s*\('

# Test: Search for the function selector. Expect: A match in the mock contract.
rg --type solidity -A 5 $'ASSETS_CONTRACT\.depositLST\.selector'

Length of output: 186


Script:

#!/bin/bash
# Description: Verify the existence and signature of the `depositLST` function and its usage in the mock contract.

# Find Solidity files and search for the depositLST function declaration
echo "Searching for depositLST function declaration:"
fd -e sol | xargs rg -n "function\s+depositLST\s*\("

# Search for the usage of depositLST selector in the mock contract
echo -e "\nSearching for depositLST selector usage in mock contract:"
rg -n "ASSETS_CONTRACT\.depositLST\.selector" test/mocks/PrecompileCallerMock.sol

# Search for IAssets interface definition
echo -e "\nSearching for IAssets interface definition:"
fd -e sol | xargs rg -n "interface\s+IAssets"

Length of output: 762

script/11_SetPeers.s.sol (2)

5-5: LGTM!

The import statement change is consistent with the list of alterations and improves code readability by directly importing the Action enum.


54-54: Verify the nativeFee calculation change.

The change in the argument passed to abi.encodePacked is consistent with the import statement change and looks good.

However, the nativeFee calculation change is not mentioned in the list of alterations or PR objectives. Please verify if this change aligns with the PR objectives or linked issues and explain its implications on the transaction cost for marking a bootstrap.

src/core/BootstrapLzReceiver.sol (3)

29-29: LGTM!

The changes to use the Errors library for handling UnexpectedSourceChain and UnsupportedRequest errors are good improvements. They promote consistency, maintainability, and clarity in the error handling logic of the contract.

Also applies to: 38-38


42-42: Looks good!

Updating the revert statement to use the Errors library for handling RequestOrResponseExecuteFailed error is a positive change. It aligns with the goal of using the Errors library for structured and consistent error handling throughout the contract.


8-8: Verify the usage of the imported Action type.

The Action type is imported from GatewayStorage.sol, but its usage remains unchanged in the provided code. Please ensure that the imported type is actually used in the contract. If not, consider removing the import to keep the code clean and maintainable.

Run the following script to verify the usage of Action:

Verification successful

Verified: The Action import is correctly used in the contract.

The Action type, imported from GatewayStorage.sol, is indeed used in the BootstrapLzReceiver.sol contract. It's utilized to create an Action instance from the payload and then compared against a specific action (Action.RESPOND). This usage justifies the import statement, and no changes are necessary.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the imported `Action` type in the contract.

# Test: Search for the usage of `Action` in the contract. Expect: At least one occurrence.
rg --type solidity -w $'Action' $(fd --type f --extension sol --regex '.*BootstrapLzReceiver\.sol')

Length of output: 164


Script:

#!/bin/bash
# Description: Verify the usage of the imported `Action` type in the BootstrapLzReceiver.sol contract.

# Find the exact path of the BootstrapLzReceiver.sol file
file_path=$(fd --type f --extension sol --regex '.*BootstrapLzReceiver\.sol')

# Search for 'Action' in the file with 2 lines of context before and after
rg -C 2 '\bAction\b' "$file_path"

# If no results, check if the file exists and show its content
if [ $? -ne 0 ]; then
    echo "File content:"
    cat "$file_path"
fi

Length of output: 747

script/TestPrecompileErrorFixed_Deploy.s.sol (1)

8-8: Verify the necessity of importing Action.

The import statement has been modified to include Action along with GatewayStorage. However, there doesn't seem to be any direct usage of Action in the rest of the script.

Please ensure that Action is actually required for the script's functionality. If it's not being used, consider removing the import to maintain code clarity and avoid unnecessary dependencies.

To verify the usage of Action, run the following script:

Verification successful

Keep the Action import for consistency and potential use.

While the Action enum isn't directly used in the visible part of the TestPrecompileErrorFixed_Deploy.s.sol script, its import is still valid for the following reasons:

  1. Action is part of the GatewayStorage import, so it's indirectly imported anyway.
  2. Action is widely used across the project, suggesting it might be needed for type consistency or in inherited contracts.
  3. The import might be anticipating future use in this deployment script.

You can keep the import as is for consistency with other files and potential future use. However, if you prefer to minimize imports, you could remove Action from the explicit import since it's already included via GatewayStorage.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if `Action` is used in the script.

# Test: Search for the usage of `Action`. Expect: No occurrences.
rg --type solidity -w Action script/TestPrecompileErrorFixed_Deploy.s.sol

Length of output: 108


Script:

#!/bin/bash
# Description: Verify file existence, content, and usage of 'Action'

# Test 1: Check if the file exists and show its content
echo "File content:"
cat script/TestPrecompileErrorFixed_Deploy.s.sol

# Test 2: Search for 'Action' in the specific file
echo -e "\nSearching for 'Action' in TestPrecompileErrorFixed_Deploy.s.sol:"
grep -n "Action" script/TestPrecompileErrorFixed_Deploy.s.sol

# Test 3: Search for 'Action' in all .sol files
echo -e "\nSearching for 'Action' in all .sol files:"
find . -name "*.sol" -type f | xargs grep -n "Action"

Length of output: 30927

src/libraries/ActionAttributes.sol (7)

1-4: LGTM!

The SPDX license identifier, Solidity version pragma, and import statement are correctly specified.


6-23: LGTM!

The ActionAttributes library is correctly defined with appropriate constants for message lengths, operation type bitmaps, and message length masking/shifting.


24-57: LGTM!

The getAttributes function is well-structured and correctly determines the attributes and message length based on the input Action. The bitwise operations used to combine the attributes and message length are appropriate.


59-61: LGTM!

The isLST function correctly checks if the given action is associated with LST by calling getAttributes and using a bitwise AND operation.


63-65: LGTM!

The isNST function correctly checks if the given action is associated with NST by calling getAttributes and using a bitwise AND operation.


67-81: LGTM!

The isWithdrawal, isPrincipal, isReward, and getMessageLength functions are correctly implemented. They call getAttributes and use appropriate bitwise operations to check the corresponding attributes or extract the message length.


83-83: LGTM!

The closing brace is correctly placed to end the ActionAttributes library definition.

src/interfaces/precompiles/IDelegation.sol (4)

28-33: LGTM!

The function renaming and parameter type changes are good improvements:

  • The new function name delegate is more concise and clear.
  • Using calldata instead of memory for read-only function parameters is more gas-efficient.

These changes enhance the code quality without altering the core functionality.


49-54: LGTM!

The function renaming and parameter type changes are consistent with the improvements made to the delegate function:

  • The new function name undelegate is more concise and clear.
  • Using calldata instead of memory for read-only function parameters is more gas-efficient.

These changes enhance the code quality and maintain consistency within the interface.


66-66: LGTM!

The parameter type changes in the associateOperatorWithStaker function are a good improvement:

  • Using calldata instead of memory for read-only function parameters is more gas-efficient.

This change enhances the code quality without altering the core functionality.


76-78: LGTM!

The parameter type change in the dissociateOperatorFromStaker function is a good improvement:

  • Using calldata instead of memory for read-only function parameters is more gas-efficient.

This change enhances the code quality and maintains consistency with the other function parameter type changes in the interface.

src/core/LSTRestakingController.sol (4)

40-41: LGTM!

The changes to the _processRequest call in the deposit function are appropriate:

  • Using Action.REQUEST_DEPOSIT_LST correctly indicates that the deposit is a must-succeed action.
  • Passing an empty bytes argument is suitable since no response is expected for a must-succeed action.

61-62: LGTM!

The changes to the _processRequest call in the withdrawPrincipalFromExocore function are appropriate:

  • Using Action.REQUEST_WITHDRAW_LST correctly indicates a withdrawal of LST tokens.
  • The comment rightly emphasizes the importance of checking the response to unlock the principal for later claims.

77-78: LGTM!

The changes to the _processRequest call in the withdrawRewardFromExocore function are appropriate:

  • Using Action.REQUEST_CLAIM_REWARD correctly indicates a reward claim operation.
  • The comment rightly emphasizes the importance of checking the response to unlock the reward for later claims.

98-100: LGTM!

The changes to the _processRequest call in the depositThenDelegateTo function are appropriate:

  • Retaining the Action.REQUEST_DEPOSIT_THEN_DELEGATE_TO action type correctly indicates a combined deposit and delegation operation.
  • Passing an empty bytes argument is suitable since no response is expected for must-succeed actions.
  • The comment aptly justifies not checking the response, as both deposit and delegation are treated as must-succeed actions.
script/5_Withdraw.s.sol (2)

8-8: LGTM!

The import change is a good refactoring that improves code readability and maintainability by directly importing the Action enum from GatewayStorage. This change aligns with the PR objective of separating NST and LST messages during deposit and withdrawal operations.


60-60: Verify the usage of the new action across the codebase.

The change from GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE to Action.REQUEST_WITHDRAW_LST aligns with the PR objective of separating NST and LST messages during deposit and withdrawal operations. This change indicates a focus on a different withdrawal mechanism, which may have implications for the overall functionality and flow of the contract.

Please ensure that the new withdrawal mechanism is properly implemented and thoroughly tested to avoid any potential issues or bugs.

Run the following script to verify the usage of the new action across the codebase:

Verification successful

Verification successful: New action consistently implemented across the codebase

The change from GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE to Action.REQUEST_WITHDRAW_LST has been successfully implemented across the codebase. The new action is consistently used in various parts of the project, including:

  • Scripts (e.g., script/5_Withdraw.s.sol)
  • Core contracts (e.g., src/core/ExocoreGateway.sol, src/core/LSTRestakingController.sol)
  • Libraries (e.g., src/libraries/ActionAttributes.sol)
  • Test files (e.g., test/foundry/DepositWithdrawPrinciple.t.sol)
  • Mock contracts (e.g., test/mocks/ExocoreGatewayMock.sol)

This change aligns with the PR objective of separating NST and LST messages during deposit and withdrawal operations. The consistent implementation suggests that the new withdrawal mechanism for LST has been properly integrated into the system.

To ensure the reliability of this change, please make sure to thoroughly test all affected components, particularly focusing on the LST withdrawal process and its interactions with other parts of the system.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of the new action `Action.REQUEST_WITHDRAW_LST` across the codebase.

# Test 1: Search for the usage of the old action. Expect: No occurrences.
rg --type solidity $'GatewayStorage\.Action\.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE'

# Test 2: Search for the usage of the new action. Expect: Only valid occurrences.
rg --type solidity -A 5 $'Action\.REQUEST_WITHDRAW_LST'

Length of output: 209


Script:

#!/bin/bash
# Description: Verify the usage of the new action `Action.REQUEST_WITHDRAW_LST` across the codebase.

# Find all Solidity files
solidity_files=$(fd -e sol)

# Test 1: Search for the usage of the old action. Expect: No occurrences.
echo "Searching for old action:"
echo "$solidity_files" | xargs grep -n "GatewayStorage\.Action\.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE" || echo "No occurrences found (as expected)"

# Test 2: Search for the usage of the new action. Expect: Only valid occurrences.
echo -e "\nSearching for new action:"
echo "$solidity_files" | xargs grep -n -A 5 "Action\.REQUEST_WITHDRAW_LST"

Length of output: 19958

script/4_Deposit.s.sol (2)

60-60: Verify the handling logic for the REQUEST_DEPOSIT_LST action.

The change from REQUEST_DEPOSIT to REQUEST_DEPOSIT_LST aligns with the PR objective of separating NST and LST deposit messages.

Please ensure that the REQUEST_DEPOSIT_LST action is correctly handled in the ClientChainGateway and ExocoreGateway contracts.

Run the following script to verify the action handling:

#!/bin/bash
# Description: Verify the handling logic for the `REQUEST_DEPOSIT_LST` action.

# Test 1: Search for the action handling in the `ClientChainGateway` contract. Expect: A `case` statement for `Action.REQUEST_DEPOSIT_LST`.
rg --type solidity -A 10 $'case Action.REQUEST_DEPOSIT_LST' ./src/ClientChainGateway.sol

# Test 2: Search for the action handling in the `ExocoreGateway` contract. Expect: A `case` statement for `Action.REQUEST_DEPOSIT_LST`.
rg --type solidity -A 10 $'case Action.REQUEST_DEPOSIT_LST' ./src/ExocoreGateway.sol

7-7: Verify the Action enum definition.

The import statement change looks good. It improves code readability by directly importing the Action enum.

Please ensure that the Action enum is correctly defined in the GatewayStorage contract.

Run the following script to verify the enum definition:

Verification successful

Verification successful: Action enum is correctly defined.

The Action enum is properly defined in src/storage/GatewayStorage.sol with the expected values, including REQUEST_DEPOSIT_LST. The import statement in script/4_Deposit.s.sol is correct and consistent with its usage across the project.

  • The Action enum is defined in src/storage/GatewayStorage.sol (line 7)
  • It includes the values: REQUEST_DEPOSIT_LST, REQUEST_DEPOSIT_NST, REQUEST_WITHDRAW_LST, REQUEST_WITHDRAW_NST, REQUEST_CLAIM_REWARD
  • The import statement is used consistently in multiple files throughout the project
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the `Action` enum definition in the `GatewayStorage` contract.

# Test: Search for the enum definition. Expect: The `Action` enum with `REQUEST_DEPOSIT_LST` value.
rg --type solidity -A 5 $'enum Action' ./src/storage/GatewayStorage.sol

Length of output: 241


Script:

#!/bin/bash
# Description: Verify the `Action` enum definition in Solidity files

# Search for Solidity files and grep for the Action enum definition
fd -e sol | xargs grep -n -A 5 "enum Action"

# Search for usage of Action enum in case statements
fd -e sol | xargs grep -n "case Action\."

# Search for import statements related to Action
fd -e sol | xargs grep -n "import.*Action"

Length of output: 3532

test/mocks/DelegationMock.sol (6)

30-35: LGTM!

The function renaming and parameter type changes improve readability and efficiency. The changes align with the PR objective of separating NST and LST messages during deposit and withdrawal operations.


52-57: LGTM!

Similar to the delegate function, the renaming and parameter type changes in the undelegate function improve readability and efficiency. The changes align with the PR objective.


77-77: LGTM!

The parameter type changes in the associateOperatorWithStaker function improve efficiency by using calldata instead of memory for external function calls.


92-95: LGTM!

The parameter type change in the dissociateOperatorFromStaker function improves efficiency by using calldata instead of memory for the staker parameter in external function calls.


108-108: LGTM!

The parameter type change in the getDelegateAmount function improves efficiency by using calldata instead of memory for the operator parameter.


116-116: LGTM!

The parameter type change in the getAssociatedOperator function improves efficiency by using calldata instead of memory for the staker parameter in external function calls.

src/core/BaseRestakingController.sol (4)

9-9: LGTM!

The import statement is correct and necessary for using the Action enum within the contract.


44-46: LGTM!

The code segment correctly handles the withdrawal of the native staking token (NST) from the associated ExoCapsule contract. It uses the VIRTUAL_NST_ADDRESS constant to identify the NST token and calls the withdraw function on the retrieved ExoCapsule contract instance to transfer the specified amount to the recipient.


67-67: LGTM!

The code segments correctly call the _processRequest function to process the delegation and undelegation requests. The actionArgs parameter is constructed by encoding the necessary values, and the encodedRequest is passed as an empty bytes array.

Passing an empty encodedRequest suggests that these requests do not expect a response that needs to be cached. This simplifies the request processing logic and reduces the overhead of managing request states.

Also applies to: 82-82


86-96: LGTM!

The code segment correctly implements the conditional registration of requests based on the length of the encodedRequest. If the encodedRequest is not empty, it means the request expects a response and needs to be cached.

The _registeredRequests and _registeredRequestActions mappings are used to store the encodedRequest and corresponding action associated with the requestNonce. This allows the contract to track and manage requests that expect a response.

The conditional registration provides flexibility in handling different types of requests and optimizes the storage usage by only registering requests that require caching.

script/TestPrecompileErrorFixed.s.sol (3)

11-11: LGTM!

The change to the import statement is correct and allows for more concise references to action types within the contract.


97-97: Verify the action type change in the codebase.

The change from GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE to Action.REQUEST_WITHDRAW_LST is correct. However, ensure that all references to this action have been updated to match the new type.

Run the following script to verify the action usage:

Verification successful

Action type change successfully verified across the codebase

The change from GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE to Action.REQUEST_WITHDRAW_LST has been consistently implemented throughout the codebase. No instances of the old action type were found, and the new action type is used appropriately in various contexts, including:

  • Function selector mappings
  • Message processing
  • Event emissions
  • Test cases and mock implementations

This verification confirms that the action type change has been applied thoroughly and consistently.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all references to `GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE` have been updated to `Action.REQUEST_WITHDRAW_LST`.

# Test: Search for the old action usage. Expect: No occurrences.
rg --type solidity $'GatewayStorage\.Action\.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE'

# Test: Search for the new action usage. Expect: Only occurrences of the new type.
rg --type solidity -A 5 $'Action\.REQUEST_WITHDRAW_LST'

Length of output: 209


Script:

#!/bin/bash
# Description: Verify all references to `GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE` have been updated to `Action.REQUEST_WITHDRAW_LST`.

# Test: Search for the old action usage. Expect: No occurrences.
rg -g '*.sol' 'GatewayStorage\.Action\.REQUEST_WITHDRAW_PRINCIPAL_FROM_EXOCORE'

# Test: Search for the new action usage. Expect: Only occurrences of the new type.
rg -g '*.sol' -A 5 'Action\.REQUEST_WITHDRAW_LST'

Length of output: 10151


76-76: Verify the action type change in the codebase.

The change from GatewayStorage.Action.REQUEST_DEPOSIT to Action.REQUEST_DEPOSIT_LST is correct. However, ensure that all references to this action have been updated to match the new type.

Run the following script to verify the action usage:

Verification successful

Verification of action type change completed successfully.

The change from GatewayStorage.Action.REQUEST_DEPOSIT to Action.REQUEST_DEPOSIT_LST has been correctly implemented and is consistent throughout the codebase. Key findings:

  1. The old action type GatewayStorage.Action.REQUEST_DEPOSIT is no longer present in any Solidity files.
  2. The new action type Action.REQUEST_DEPOSIT_LST is used consistently in relevant parts of the codebase, including tests, core logic, and deployment scripts.
  3. Related action types like REQUEST_DEPOSIT_NST and REQUEST_DEPOSIT_THEN_DELEGATE_TO are also present, indicating a comprehensive update to the action system.

The change appears to be part of a broader refactoring or feature update, and has been implemented thoroughly across the project.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all references to `GatewayStorage.Action.REQUEST_DEPOSIT` have been updated to `Action.REQUEST_DEPOSIT_LST`.

# Test: Search for the old action usage. Expect: No occurrences.
rg --type solidity $'GatewayStorage\.Action\.REQUEST_DEPOSIT'

# Test: Search for the new action usage. Expect: Only occurrences of the new type.
rg --type solidity -A 5 $'Action\.REQUEST_DEPOSIT_LST'

Length of output: 184


Script:

#!/bin/bash
# Description: Verify all references to `GatewayStorage.Action.REQUEST_DEPOSIT` have been updated to `Action.REQUEST_DEPOSIT_LST`.

# Find all Solidity files
echo "Solidity files in the repository:"
fd -e sol

# Search for the old action usage. Expect: No occurrences.
echo -e "\nSearching for old action usage (GatewayStorage.Action.REQUEST_DEPOSIT):"
fd -e sol | xargs rg 'GatewayStorage\.Action\.REQUEST_DEPOSIT'

# Search for the new action usage. Expect: Only occurrences of the new type.
echo -e "\nSearching for new action usage (Action.REQUEST_DEPOSIT_LST):"
fd -e sol | xargs rg -A 5 'Action\.REQUEST_DEPOSIT_LST'

# Search for any remaining references to REQUEST_DEPOSIT
echo -e "\nSearching for any remaining references to REQUEST_DEPOSIT:"
fd -e sol | xargs rg 'REQUEST_DEPOSIT'

Length of output: 18295

test/foundry/WithdrawReward.t.sol (10)

4-4: LGTM!

The import statement is correct and the imported types are likely used in the test contract.


16-16: LGTM!

The ClaimRewardResult event declaration is correct and consistent with the AI-generated summary.


39-39: LGTM!

The usage of the Action.REQUEST_CLAIM_REWARD constant is correct and consistent with the AI-generated summary.


57-57: LGTM!

The MessageSent event expectation is correctly updated to use the Action.REQUEST_CLAIM_REWARD constant, which is consistent with the AI-generated summary.


67-75: LGTM!

The withdrawResponsePayload construction and the ClaimRewardResult event expectation are correctly updated to use the Action.RESPOND constant and the new event name and parameters, which is consistent with the AI-generated summary.


87-87: LGTM!

The MessageSent event expectation is correctly updated to use the Action.RESPOND constant, which is consistent with the AI-generated summary.


90-90: LGTM!

The MessageExecuted event expectation is correctly updated to use the Action.REQUEST_CLAIM_REWARD constant, which is consistent with the AI-generated summary.


107-107: LGTM!

The ResponseProcessed event expectation is correctly updated to use the Action.REQUEST_CLAIM_REWARD constant, which is consistent with the AI-generated summary.


110-110: LGTM!

The MessageExecuted event expectation is correctly updated to use the Action.RESPOND constant, which is consistent with the AI-generated summary.


1-3: Skipped reviewing the remaining code.

The remaining code in the file does not have any annotated changes, so it can be assumed to be unchanged. Reviewing unchanged code is not necessary for this review.

Also applies to: 5-15, 17-38, 40-56, 58-66, 76-86, 88-89, 91-106, 108-109, 111-123

script/13_DepositValidator.s.sol (2)

8-8: LGTM!

The change to use destructured import syntax for importing the Action enum along with GatewayStorage is a good improvement. It allows direct usage of the Action enum in the code, which improves readability and suggests that the enum will be used for deposit-related actions.


77-77: Excellent change to align with the PR objective!

The modification of the first argument in the msg_ construction from GatewayStorage.Action.REQUEST_DEPOSIT to Action.REQUEST_DEPOSIT_LST is a great change that aligns perfectly with the PR objective of separating NST (Native Staking Token) and LST (Liquid Staking Token) deposit/withdrawal messages.

By using Action.REQUEST_DEPOSIT_LST, it clearly indicates that this deposit action is specifically for LST, helping to distinguish it from NST deposit actions. This change enhances the clarity and maintainability of the code.

src/storage/ClientChainGatewayStorage.sol (3)

6-7: LGTM!

The import statement for the Errors library is syntactically correct and the relative import path appears to be valid.


79-83: LGTM!

The ResponseProcessed event declaration is syntactically correct and the indexed parameters provide clear semantics about the purpose of the event. The change from RequestFinished to ResponseProcessed better reflects the event's purpose without altering the contract's functionality or event consumption.


116-116: LGTM!

The reference to the Errors library's CapsuleNotExist() error is correct and consistent with the previous custom error. Centralizing error definitions in the Errors library can improve maintainability and consistency across the contract's error handling without causing any issues in the contract's functionality.

src/interfaces/precompiles/IAssets.sol (4)

26-31: LGTM!

The changes to the depositLST function improve clarity and gas efficiency:

  • The function name clearly indicates that it is for depositing LSTs.
  • Using calldata for assetsAddress and stakerAddress parameters is more gas-efficient compared to memory.

The functionality remains the same, with the changes enhancing the code quality.


43-48: New function for depositing NSTs looks good!

The addition of the depositNST function enhances the contract's capability to handle different asset types:

  • The function is specifically designed for depositing NSTs, complementing the existing depositLST function.
  • The inclusion of validatorPubkey as a parameter indicates that this function is tailored for handling NSTs.
  • The use of calldata for parameters follows best practices for gas optimization.

The new function is a valuable addition to the contract's functionality.


58-63: LGTM!

The changes to the withdrawLST function improve clarity and gas efficiency:

  • The function name clearly indicates that it is for withdrawing LSTs.
  • Using calldata for assetsAddress and withdrawAddress parameters is more gas-efficient compared to memory.

The functionality remains the same, with the changes enhancing the code quality.


73-78: New function for withdrawing NSTs looks good!

The addition of the withdrawNST function enhances the contract's capability to handle different asset types:

  • The function is specifically designed for withdrawing NSTs, complementing the existing withdrawLST function.
  • The inclusion of validatorPubkey as a parameter indicates that this function is tailored for handling NSTs.
  • The use of calldata for parameters follows best practices for gas optimization.

The new function is a valuable addition to the contract's functionality.

src/core/ClientChainGateway.sol (1)

132-132: The change looks good, but please clarify the broader context and implications.

The conditional check has been updated from VIRTUAL_STAKED_ETH_ADDRESS to VIRTUAL_NST_ADDRESS, which aligns with the error message NoTvlLimitForNativeRestaking. This suggests a shift in the token being referenced for the TVL limit logic, potentially impacting how the contract handles native restaking.

To better understand the full impact of this change, please provide more context on:

  1. The difference between VIRTUAL_STAKED_ETH_ADDRESS and VIRTUAL_NST_ADDRESS.
  2. How this change affects the contract's handling of native restaking.

Also, consider adding comments to explain the purpose and implications of this change for future maintainers.

To verify the usage of VIRTUAL_NST_ADDRESS, run the following script:

Verification successful

The change from VIRTUAL_STAKED_ETH_ADDRESS to VIRTUAL_NST_ADDRESS is correct and consistent.

The update to use VIRTUAL_NST_ADDRESS instead of VIRTUAL_STAKED_ETH_ADDRESS in the core contracts is part of a broader refactoring to support native staking scenarios. The functionality associated with this constant remains the same, used to identify and handle native staked ETH differently from other tokens.

However, for improved consistency and maintainability:

  1. Consider updating remaining instances of VIRTUAL_STAKED_ETH_ADDRESS in test files and scripts to use VIRTUAL_NST_ADDRESS.
  2. Add a comment explaining the purpose of VIRTUAL_NST_ADDRESS where it's defined, for better code readability.

Example comment:

// VIRTUAL_NST_ADDRESS represents the special address for native staked ETH
address internal constant VIRTUAL_NST_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the usage of `VIRTUAL_NST_ADDRESS` in the codebase.

# Test: Search for the usage of `VIRTUAL_NST_ADDRESS`. Expect: Relevant usage in the codebase.
rg --type solidity -A 5 $'VIRTUAL_NST_ADDRESS'

Length of output: 78


Script:

#!/bin/bash
# Description: Search for VIRTUAL_NST_ADDRESS and VIRTUAL_STAKED_ETH_ADDRESS in Solidity files

# Search for VIRTUAL_NST_ADDRESS
echo "Searching for VIRTUAL_NST_ADDRESS:"
fd -e sol | xargs grep -n -C 3 "VIRTUAL_NST_ADDRESS"

echo -e "\n------------------------\n"

# Search for VIRTUAL_STAKED_ETH_ADDRESS
echo "Searching for VIRTUAL_STAKED_ETH_ADDRESS:"
fd -e sol | xargs grep -n -C 3 "VIRTUAL_STAKED_ETH_ADDRESS"

Length of output: 33162

script/3_Setup.s.sol (2)

3-3: LGTM!

The import statement is updated correctly to align with the addition of enum Action in GatewayStorage. This change enhances readability and maintainability by directly importing the required entities.


124-124: LGTM!

The usage of Action.REQUEST_ADD_WHITELIST_TOKEN is updated correctly to align with the updated import statement. This change enhances readability and maintainability by directly using the imported Action enum, while preserving the functionality of quoting the native fee for adding whitelist tokens.

src/core/NativeRestakingController.sol (3)

36-36: LGTM!

The change from VIRTUAL_STAKED_ETH_ADDRESS to VIRTUAL_NST_ADDRESS aligns with the new token model for restaking operations as mentioned in the PR summary. The code change looks good.


105-109: Looks good!

The code changes align with the PR objectives:

  • Including the validator's public key in the action arguments facilitates sending it to Exocore for recording purposes.
  • Updating the action name to REQUEST_DEPOSIT_NST reflects the new token type being used for deposits.
  • Simplifying the encoded request to an empty byte array indicates that the deposit action is now a must-succeed operation.

The implementation looks correct and the changes make sense in the context of the PR.


128-133: Changes look good!

The code changes align with the PR objectives:

  • Including the validator's public key in the action arguments facilitates sending it to Exocore for recording purposes.
  • Updating the action name to REQUEST_WITHDRAW_NST reflects the new token type being used for withdrawals.
  • Referencing VIRTUAL_NST_ADDRESS in the encoded request indicates that the withdrawal process has been aligned with the new token model.

The implementation looks correct and the changes make sense in the context of the PR.

test/foundry/Delegation.t.sol (12)

6-6: LGTM!

The refactoring to import Action and GatewayStorage directly from the GatewayStorage module improves code readability and maintainability.


28-34: LGTM!

The new DelegationRequest event structure consolidates the success status, token, delegator, operator, and amount into a single event for both delegation and undelegation actions. This change enhances clarity and reduces redundancy in event handling.


Line range hint 95-100: LGTM!

The code changes to use the Action enum directly are consistent with the refactoring and look good.


116-116: LGTM!

The MessageSent event emission update to use the Action.REQUEST_DELEGATE_TO enum value is consistent with the refactoring and looks good.


139-146: LGTM!

The replacement of the DelegateResult event emission with the new DelegationRequest event emission is consistent with the consolidated event structure and looks good.


149-149: LGTM!

The MessageExecuted event emission update to use the Action.REQUEST_DELEGATE_TO enum value is consistent with the refactoring and looks good.


Line range hint 180-185: LGTM!

The code changes to use the Action enum directly are consistent with the refactoring and look good.


201-201: LGTM!

The MessageSent event emission update to use the Action.REQUEST_UNDELEGATE_FROM enum value is consistent with the refactoring and looks good.


224-231: LGTM!

The replacement of the UndelegateResult event emission with the new DelegationRequest event emission is consistent with the consolidated event structure and looks good.


234-234: LGTM!

The MessageExecuted event emission update to use the Action.REQUEST_UNDELEGATE_FROM enum value is consistent with the refactoring and looks good.


139-146: This code segment has already been reviewed earlier. Please refer to the previous comments.


224-231: This code segment has already been reviewed earlier. Please refer to the previous comments.

test/foundry/unit/ClientChainGateway.t.sol (5)

28-28: LGTM!

The changes to the import statement and the MessageSent event declaration improve modularity and readability by directly using the Action enum instead of referencing it through the GatewayStorage contract.

Also applies to: 71-71


Line range hint 1-1:


Line range hint 1-1:


335-335: LGTM!

Referencing the CapsuleNotExist error selector from the centralized Errors library improves maintainability and reduces dependencies on specific storage contracts.


378-378: LGTM!

The changes in this contract improve consistency and maintainability by:

  • Utilizing the Action enum directly in message encoding, reducing dependencies on the GatewayStorage contract.
  • Referencing the VaultNotExist error selector from the centralized Errors library, reducing dependencies on specific storage contracts.

Also applies to: 387-387, 397-397

src/storage/BootstrapStorage.sol (3)

129-130: LGTM!

The introduction of the VIRTUAL_NST_ADDRESS constant to represent the virtual address for the native staking token is a clear and concise addition.


324-324: LGTM!

Replacing the custom error VaultNotExist with the namespaced error reference Errors.VaultNotExist() improves code organization and maintainability by centralizing error definitions.


338-340: LGTM!

The added check to revert if the underlyingToken is equal to VIRTUAL_NST_ADDRESS when deploying a vault is a good safety measure. It prevents accidentally deploying a vault for the virtual native staking token address, which could lead to unexpected behavior or errors.

test/foundry/ExocoreDeployer.t.sol (5)

22-22: LGTM!

Importing Action directly alongside GatewayStorage is a good way to reduce verbosity when referencing Action later in the code.


111-115: Approve the event signature changes.

The modifications to the MessageSent and RequestFinished events are good changes:

  • Directly referencing Action in the MessageSent event is consistent with the updated import statement and enhances clarity.
  • Renaming RequestFinished to ResponseProcessed suggests a shift in focus from a request-centric to a response-centric model. This indicates a broader conceptual change in how the contract processes messages, possibly indicating a more robust handling of responses.

Line range hint 186-201: LGTM!

The changes in the setUp function are good:

  • Directly using Action.REQUEST_ADD_WHITELIST_TOKEN in the payload construction enhances readability.
  • The modifications in the emit statements ensure that all references to actions are consistent and clear.

Line range hint 224-236: LGTM!

The updated emit statements are consistent with the previous changes and ensure clarity and consistency throughout the contract.


469-477: Approve the new utility functions.

The addition of the _addressToBytes and _getPrincipalBalance functions is a good enhancement to the contract's functionality:

  • These utility methods can be reused in various contexts within the contract, promoting code reusability and maintainability.
  • The functions are properly implemented, follow the correct syntax, and are appropriately marked as internal.
test/foundry/unit/ExocoreGateway.t.sol (11)

55-55: LGTM!

The MessageSent event has been updated to use the Action type, which is consistent with the goal of streamlining the naming convention across the codebase.


186-186: LGTM!

The AssociateOperatorResult and DissociateOperatorResult events have been consolidated into a single AssociationResult event, which improves code maintainability and enhances semantic clarity with the addition of the isAssociate parameter.


208-208: LGTM!

The REQUEST_WITHDRAW_LST action has been updated to use the Action type, which is consistent with the goal of streamlining the naming convention across the codebase.


224-224: LGTM!

The REQUEST_ASSOCIATE_OPERATOR action has been updated to use the Action type, and the emitted event has been updated to AssociationResult with the isAssociate parameter set to true, which is consistent with the goal of streamlining the naming convention and enhancing semantic clarity across the codebase.

Also applies to: 227-227


246-246: LGTM!

The REQUEST_ASSOCIATE_OPERATOR action has been updated to use the Action type, and the emitted event has been updated to AssociationResult with the isAssociate parameter set to true, which is consistent with the goal of streamlining the naming convention and enhancing semantic clarity across the codebase.

Also applies to: 249-249


274-274: LGTM!

The REQUEST_ASSOCIATE_OPERATOR action has been updated to use the Action type, and the emitted event has been updated to AssociationResult with the isAssociate parameter set to true, which is consistent with the goal of streamlining the naming convention and enhancing semantic clarity across the codebase.

Also applies to: 288-288


311-311: LGTM!

The REQUEST_DISSOCIATE_OPERATOR action has been updated to use the Action type, and the emitted event has been updated to AssociationResult with the isAssociate parameter set to false, which is consistent with the goal of streamlining the naming convention and enhancing semantic clarity across the codebase.

Also applies to: 314-314


330-330: LGTM!

The REQUEST_DISSOCIATE_OPERATOR action has been updated to use the Action type, and the emitted event has been updated to AssociationResult with the isAssociate parameter set to false, which is consistent with the goal of streamlining the naming convention and enhancing semantic clarity across the codebase.

Also applies to: 333-333


575-575: LGTM!

The emitted event has been updated to use the Action.REQUEST_ADD_WHITELIST_TOKEN action, which is consistent with the goal of streamlining the naming convention across the codebase.


615-615: LGTM!

The emitted event has been updated to use the Action.REQUEST_ADD_WHITELIST_TOKEN action, which is consistent with the goal of streamlining the naming convention across the codebase.


773-773: LGTM!

The nativeFee calculation has been updated to use the Action.REQUEST_MARK_BOOTSTRAP action, which is consistent with the goal of streamlining the naming convention across the codebase.

src/core/Bootstrap.sol (5)

25-25: LGTM!

The import statement for the BootstrapStorage contract is correctly added.


27-27: LGTM!

The import statement for the Action enum from the GatewayStorage contract is correctly added.


218-218: LGTM!

The check to skip deploying a vault for the VIRTUAL_NST_ADDRESS token is correctly added.


239-239: LGTM!

The check to prevent updating the TVL limit for the VIRTUAL_NST_ADDRESS token is correctly added.


439-439: LGTM!

The revert statement with the Errors.NotYetSupported() error is correctly added to indicate that the withdrawRewardFromExocore function is not yet supported.

test/foundry/DepositWithdrawPrinciple.t.sol (9)

55-61: LGTM!

The test function follows a clear and concise testing flow for LST deposit and withdrawal using LayerZero. The use of helper functions improves readability, and the assertions ensure the correctness of the balances at each step.

Also applies to: 66-73


150-150: LGTM!

The LST withdrawal test function follows the expected workflow and validates the emitted events correctly. The lastlyUpdatedPrincipalBalance is updated to keep track of the principal balance.

Also applies to: 169-169, 179-191, 204-206, 208-208, 222-222, 224-224


259-265: LGTM!

The test function follows a clear and concise testing flow for native deposit and withdrawal. The use of helper functions improves readability, and the assertions ensure the correctness of the balances at each step.

Also applies to: 284-290


309-309: LGTM!

The native deposit test function follows the expected workflow and validates the emitted events correctly. The lastlyUpdatedPrincipalBalance is updated to keep track of the principal balance.

Also applies to: 325-325, 336-347


Line range hint 362-391: LGTM!

The function performs the necessary setup steps before a native deposit, ensuring the block environment states are properly simulated and the capsule is attached to the withdrawal credentials for compatibility.


438-441: LGTM!

The native withdrawal test function follows the expected workflow and validates the emitted events correctly. The lastlyUpdatedPrincipalBalance is updated to keep track of the principal balance.

Also applies to: 458-458, 469-482, 495-495, 499-499, 511-511, 514-514


Line range hint 525-546: LGTM!

The function performs the necessary setup steps to simulate the block environment for a native withdrawal, loading the required data from a JSON file and mocking the beaconOracle.timestampToBlockRoot call.


565-573: LGTM!

The test function follows a comprehensive testing flow to validate the deposit TVL limit behavior. It performs a series of deposit and withdrawal operations, checking the consumed TVL and TVL limit values at each step. The test cases cover various scenarios, ensuring the correctness of the TVL limit implementation.

Also applies to: 585-587, 609-615, 620-621, 624-630, 640-640, 677-683, 687-687, 691-697, 708-708, 738-746, 753-755


23-29: LGTM!

The new LSTTransfer and NSTTransfer event declarations provide clear and structured information about LST and NST transfers. The inclusion of the isDeposit flag allows distinguishing between deposits and withdrawals, and the success flag indicates the status of the transfer operation. The indexed token and account parameters enable efficient event filtering.

test/foundry/unit/Bootstrap.t.sol (13)

Line range hint 1007-1038: Test looks good!

The test function test01_AddWhitelistToken is well-structured and covers the happy path scenario of adding a new token to the whitelist. It makes appropriate assertions to verify the expected behavior.


Line range hint 1040-1049: Test looks good!

The test function test01_AddWhitelistToken_AlreadyExists correctly tests the scenario when trying to add a token that already exists in the whitelist. It expects the transaction to revert with the appropriate error.


Line range hint 1051-1067: Test looks good!

The test function test01_AddWhitelistToken_NoVaultForNativeETH correctly verifies that no vault is deployed for the native ETH token when it is added to the whitelist. The test function is well-structured and makes appropriate assertions.


Line range hint 1069-1119: Test looks good!

The test function test02_Deposit thoroughly tests the deposit functionality of the Bootstrap contract. It distributes tokens to addresses, makes deposits, and checks the balances, deposit amounts, and depositor counts. The test function is well-structured and covers various scenarios.


Line range hint 1121-1130: Test looks good!

The test function test02_Deposit_WithoutApproval correctly tests the scenario of making a deposit without approving the vault. It expects the transaction to revert, which is the desired behavior.


Line range hint 1132-1141: Test looks good!

The test function test02_Deposit_ZeroBalance correctly tests the scenario of making a deposit with zero balance. It expects the transaction to revert, which is the desired behavior.


Line range hint 1143-1160: Test looks good!

The test function test02_Deposit_NonWhitelistedToken correctly tests the scenario of making a deposit with a non-whitelisted token. It expects the transaction to revert with the appropriate error message.


Line range hint 1186-1203: Test looks good!

The test function test02_Deposit_MoreThanTvl correctly tests the scenario of making a deposit that exceeds the TVL limit. It reduces the TVL limit and expects the transaction to revert with the appropriate error.


Line range hint 1205-1270: Test looks good!

The test function test02_Deposit_ReduceTvlWithdraw thoroughly tests the scenario of reducing the TVL limit and making deposits and withdrawals. It verifies that the TVL limit is enforced correctly and deposits are not allowed when the TVL is reached. The test function covers various cases and makes appropriate assertions.


Line range hint 1272-1301: Test looks good!

The test function test03_RegisterValidator thoroughly tests the validator registration functionality of the Bootstrap contract. It registers multiple validators and checks the validator count, mappings, and struct values. The test function is well-structured and covers various scenarios.


Line range hint 1303-1317: Test looks good!

The test function test03_RegisterValidator_EthAlreadyRegistered correctly tests the scenario of registering a validator with an Ethereum address that is already registered. It expects the transaction to revert with the appropriate error.


Line range hint 1319-1333: Test looks good!

The test function test03_RegisterValidator_ExoAlreadyRegistered correctly tests the scenario of registering a validator with an Exocore address that is already registered. It expects the transaction to revert with the appropriate error.


Line range hint 1335-1349: Test looks good!

The test function test03_RegisterValidator_ConsensusKeyInUse correctly tests the scenario of registering a validator with a consensus key that is already in use. It expects the transaction to revert with the appropriate error.

src/storage/GatewayStorage.sol (2)

4-4: Good use of centralized error handling with Errors library

Importing the Errors library promotes consistent and maintainable error management throughout the codebase.


86-86: Use of centralized error handling improves maintainability

Replacing inline revert statements with Errors.UnexpectedInboundNonce enhances consistency and readability in error handling.

src/storage/ExocoreGatewayStorage.sol (1)

108-126: Message Length Validation Function Implemented Correctly

The _validateMessageLength function effectively validates the message length based on the action type, ensures unsupported actions are handled, and provides specific error messages. The implementation appears correct and robust.

test/mocks/AssetsMock.sol (3)

10-10: Declaration of inValidatorSet mapping is appropriate

The mapping is correctly defined to track whether a staker is part of a validator set.


21-26: Function depositLST is correctly defined

The function signature and parameters are appropriate for handling LST deposits.


29-29: Verify address comparison logic

Ensure that the comparison between assetsAddress and VIRTUAL_STAKED_ETH_ADDRESS functions as intended. The casting and comparison may lead to unexpected results if assetsAddress is not properly formatted. Consider verifying that assetsAddress is consistently encoded.

To verify the address comparison logic, run the following script:

Verification successful

Address comparison logic is correctly implemented

The address comparison logic in AssetsMock.sol is implemented correctly and consistently. The code ensures that:

  1. assetsAddress is 32 bytes long before comparison.
  2. The comparison uses bytes32(assetsAddress) != bytes32(bytes20(VIRTUAL_STAKED_ETH_ADDRESS)).
  3. The casting of VIRTUAL_STAKED_ETH_ADDRESS to bytes20 and then to bytes32 is a standard practice for address comparisons in Solidity.

This implementation effectively excludes the virtual staked ETH address from being deposited as a Liquid Staking Token (LST), which aligns with the intended behavior.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that the address comparison logic is consistent.

# Test: Search for all usages of `assetsAddress` to ensure consistent formatting.
rg --type solidity -A 3 -B 3 'assetsAddress'

Length of output: 77


Script:

#!/bin/bash

# 1. Display the content of AssetsMock.sol
echo "Content of AssetsMock.sol:"
cat test/mocks/AssetsMock.sol

# 2. Search for 'assetsAddress' in all .sol files
echo -e "\n\nOccurrences of 'assetsAddress' in .sol files:"
rg -t sol 'assetsAddress' -A 3 -B 3

# 3. Look for similar address comparison patterns
echo -e "\n\nSimilar address comparison patterns in .sol files:"
rg -t sol 'require\(.*==.*\)' -A 3 -B 3

Length of output: 6397

src/core/ClientGatewayLzReceiver.sol (2)

89-93: Ensure all action types are handled in _handleResponse

The current implementation checks for isPrincipal() and isReward(), but if the requestAct does not match these, it reverts with UnsupportedResponse. Ensure that all valid action types are considered, or validate that only these two are expected.

Please confirm that only isPrincipal() and isReward() action types are valid in this context. If there are additional action types, they should be handled appropriately.


180-182: Validate ADD_TOKEN_WHITELIST_REQUEST_LENGTH correctly

The check for payload.length != ADD_TOKEN_WHITELIST_REQUEST_LENGTH should ensure that ADD_TOKEN_WHITELIST_REQUEST_LENGTH is defined and matches the expected payload size.

Run the following script to confirm that ADD_TOKEN_WHITELIST_REQUEST_LENGTH is correctly defined and used consistently:

Verification successful

ADD_TOKEN_WHITELIST_REQUEST_LENGTH is correctly defined and used

The constant ADD_TOKEN_WHITELIST_REQUEST_LENGTH is properly defined in src/storage/ClientChainGatewayStorage.sol as 48 bytes, which correctly represents the expected payload structure (bytes32 token + uint128 tvlLimit). It is then appropriately used in src/core/ClientGatewayLzReceiver.sol to validate the payload length before processing the request.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that ADD_TOKEN_WHITELIST_REQUEST_LENGTH matches the expected payload size.

# Test: Search for the definition and usage of ADD_TOKEN_WHITELIST_REQUEST_LENGTH.
# Expect: Definition and usage should align with the payload structure.
rg --type solidity 'ADD_TOKEN_WHITELIST_REQUEST_LENGTH'

Length of output: 88


Script:

#!/bin/bash
# Search for ADD_TOKEN_WHITELIST_REQUEST_LENGTH definition and usage
rg -C 5 'ADD_TOKEN_WHITELIST_REQUEST_LENGTH'

# Search for comments or code related to the payload structure
rg -C 5 'payload.*length|payload.*structure'

Length of output: 110713

src/libraries/Errors.sol (1)

4-4: Import Statement Properly Adds 'Action'

The import of Action from GatewayStorage.sol is necessary for the newly added error types that use the Action enum.

src/core/ExocoreGateway.sol (8)

303-303: Ensure _validateMessageLength properly checks message length

The _validateMessageLength function should adequately verify that message has the minimum required length before further processing. This prevents potential out-of-bounds errors when accessing message[0] or slicing message.


372-373: Ensure payload length is sufficient before slicing in handleNSTTransfer

Similar to handleLSTTransfer, handleNSTTransfer slices payload without a length check. Verify that payload.length >= 96 to prevent errors.

+        require(payload.length >= 96, "Payload too short in handleNSTTransfer");
         bytes calldata validatorPubkey = payload[:32];
         bytes calldata staker = payload[32:64];

427-438: Ensure payload length is sufficient before slicing in handleDelegation

Before slicing payload to extract token, staker, operator, and amount, check that payload.length >= 138 to avoid out-of-bounds errors.

+        require(payload.length >= 138, "Payload too short in handleDelegation");
         // use memory to avoid stack too deep
         bytes memory token = payload[:32];

453-466: Ensure payload length is sufficient before slicing in handleDepositAndDelegate

Verify that payload.length is adequate before slicing in handleDepositAndDelegate. This prevents potential errors due to insufficient payload size.

+        require(payload.length >= 138, "Payload too short in handleDepositAndDelegate");
         // use memory to avoid stack too deep
         bytes memory token = payload[:32];

480-489: Ensure payload length is sufficient before slicing in handleOperatorAssociation

Add a check to ensure payload.length is appropriate before slicing in handleOperatorAssociation, especially when accessing operator data.

         bool success;
+        require(payload.length >= 32, "Payload too short in handleOperatorAssociation");
         bytes calldata staker = payload[:32];

80-89: Verify action mappings in _initializeWhitelistFunctionSelectors

Ensure that each Action is correctly mapped to its corresponding handler. This is crucial for the proper routing of actions to their handlers and the overall functionality of the gateway.

Run the following script to confirm that all actions have the appropriate mappings:

Verification successful

Action mappings in _initializeWhitelistFunctionSelectors are correct

The verification process has confirmed that all Actions are correctly mapped to their corresponding handlers in the ExocoreGateway.sol file. Each mapping has been checked and found to be accurate, ensuring proper routing of actions to their respective handlers. This verification addresses the concern raised in the original review comment.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that all Actions are mapped to function selectors.

# Expected Actions and their handlers
declare -A expected_mappings=(
  ["REQUEST_DEPOSIT_LST"]="handleLSTTransfer"
  ["REQUEST_WITHDRAW_LST"]="handleLSTTransfer"
  ["REQUEST_DEPOSIT_NST"]="handleNSTTransfer"
  ["REQUEST_WITHDRAW_NST"]="handleNSTTransfer"
  ["REQUEST_CLAIM_REWARD"]="handleRewardOperation"
  ["REQUEST_DELEGATE_TO"]="handleDelegation"
  ["REQUEST_UNDELEGATE_FROM"]="handleDelegation"
  ["REQUEST_DEPOSIT_THEN_DELEGATE_TO"]="handleDepositAndDelegate"
  ["REQUEST_ASSOCIATE_OPERATOR"]="handleOperatorAssociation"
  ["REQUEST_DISSOCIATE_OPERATOR"]="handleOperatorAssociation"
)

for action in "${!expected_mappings[@]}"; do
  handler=${expected_mappings[$action]}
  grep_pattern="_whiteListFunctionSelectors\[Action\.$action\] = this\.$handler\.selector;"
  if ! grep -q "$grep_pattern" src/core/ExocoreGateway.sol; then
    echo "Mapping for $action to $handler is missing or incorrect."
  else
    echo "Mapping for $action to $handler is correct."
  fi
done

Length of output: 5407


289-289: Improve error handling in _registerOrUpdateClientChain

The function currently reverts with a custom error if success is false but doesn't provide information about the underlying cause. Consider including the failure reason from ASSETS_CONTRACT.registerOrUpdateClientChain to aid in debugging.

Update the code to capture and use the failure reason:

         (bool success, bool updated) = ASSETS_CONTRACT.registerOrUpdateClientChain(
             clientChainId, addressLength, name, metaInfo, signatureType
         );
-        if (!success) {
+        if (!success || !updated) {
             revert Errors.RegisterClientChainToExocoreFailed(clientChainId);
         }

Likely invalid or redundant comment.


6-6: Remove duplicate import of Errors.sol

The Errors.sol library is imported twice in this contract, which is unnecessary and may cause confusion or compiler warnings. Removing the duplicate import will clean up the code.

Apply this diff to fix the issue:

...
---

Likely invalid or redundant comment.

test/mocks/ExocoreGatewayMock.sol (5)

81-86: Zero address check in initialize function is appropriate

The inclusion of a zero address check for the owner_ parameter in the initialize function ensures that the contract owner cannot be set to the zero address, which could lead to loss of control over contract functions.


119-121: Consider restricting access to markBootstrap function

The markBootstrap function is publicly accessible, allowing any user to send a bootstrap request to a chain. Confirm if this open accessibility is intended. If not, consider adding access control modifiers such as onlyOwner or a role-based check to restrict this function to authorized entities.

Also applies to: 126-127


173-176: Verified client chain ID before setting peer

Adding _validateClientChainIdRegistered(clientChainId) ensures that only registered client chain IDs can have a peer set. This enhances security by preventing unauthorized or unregistered chains from being configured.


312-332: Verify security of dynamic function calls in _lzReceive

The _lzReceive function uses address(this).call to invoke handlers based on function selectors retrieved from _whiteListFunctionSelectors. Ensure that this mechanism is secure against potential exploits, such as unauthorized function calls or reentrancy attacks. All callable functions should be carefully audited to prevent unintended side effects.


400-418: Confirm non-reverting behavior on reward claim failure in handleRewardOperation

In handleRewardOperation, the function does not revert if CLAIM_REWARD_CONTRACT.claimReward fails; instead, it includes the success status in the response. Verify that this approach aligns with the intended contract logic and that failure scenarios are adequately handled and communicated to the client chain.

src/storage/ExocoreGatewayStorage.sol Outdated Show resolved Hide resolved
src/storage/ExocoreGatewayStorage.sol Outdated Show resolved Hide resolved
src/storage/ExocoreGatewayStorage.sol Outdated Show resolved Hide resolved
src/storage/ExocoreGatewayStorage.sol Outdated Show resolved Hide resolved
test/mocks/AssetsMock.sol Show resolved Hide resolved
src/core/ExocoreGateway.sol Show resolved Hide resolved
src/core/ExocoreGateway.sol Outdated Show resolved Hide resolved
test/mocks/ExocoreGatewayMock.sol Show resolved Hide resolved
test/mocks/ExocoreGatewayMock.sol Show resolved Hide resolved
test/mocks/ExocoreGatewayMock.sol Show resolved Hide resolved
Copy link
Collaborator

@bwhour bwhour left a comment

Choose a reason for hiding this comment

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

please resolve the coderabitai report. the whole looks good.

src/core/ExocoreGateway.sol Show resolved Hide resolved
src/core/NativeRestakingController.sol Show resolved Hide resolved
@MaxMustermann2
Copy link
Collaborator

Does this also close #57 ?

@adu-web3
Copy link
Collaborator Author

Does this also close #57 ?

yes, exactly, it also closes #3

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

Outside diff range and nitpick comments (15)
src/libraries/Errors.sol (3)

126-138: Approve new errors with a suggestion for improvement

The new errors VaultDoesNotExist and RequestOrResponseExecuteFailed are well-defined and provide clear error handling. However, the NotYetSupported error could benefit from additional context.

Consider adding a parameter to NotYetSupported to provide more context about which operation is not yet supported. For example:

-error NotYetSupported();
+error NotYetSupported(string operation);

This would make debugging and error handling more informative.


246-250: Approve DepositRequestShouldNotFail error with a suggestion

The DepositRequestShouldNotFail error is well-documented and provides crucial information for debugging failed deposit requests. The inclusion of srcChainId and lzNonce parameters is particularly useful for tracing issues across chains.

Consider renaming the error to better reflect its critical nature:

-error DepositRequestShouldNotFail(uint32 srcChainId, uint64 lzNonce);
+error CriticalDepositRequestFailure(uint32 srcChainId, uint64 lzNonce);

This name more clearly communicates the severity of the error to developers.


266-270: Approve new whitelist token errors with suggestions

The InvalidWhitelistTokensInput and WhitelistTokensListTooLong errors are clear additions that will help in managing whitelist token operations. They align with the PR objectives for improving token management across chains.

Consider adding parameters to these errors to provide more context:

-error InvalidWhitelistTokensInput();
+error InvalidWhitelistTokensInput(uint256 expectedLength, uint256 actualLength);

-error WhitelistTokensListTooLong();
+error WhitelistTokensListTooLong(uint256 maxLength, uint256 actualLength);

These additions would make debugging and error handling more informative.

src/storage/BootstrapStorage.sol (2)

324-324: LGTM: Improved error handling in _getVault

The switch to Errors.VaultDoesNotExist() represents a positive move towards centralized error handling, which can enhance code consistency and maintainability. This approach aligns with best practices for error management in Solidity.

Consider adding a custom error message to provide more context, e.g., Errors.VaultDoesNotExist(token). This would help in debugging by immediately identifying which token's vault is missing.


338-340: LGTM: Prevention of vault deployment for NST

The addition of this check aligns with the PR's objective to handle Native Staking Tokens (NST) differently. Preventing vault deployment for NST is a logical step, as native tokens typically don't require a separate vault.

Consider making the error message more specific, e.g., Errors.CannotDeployVaultForNST(). This would provide clearer context about why the vault deployment is forbidden specifically for the native staking token.

test/mocks/ExocoreGatewayMock.sol (10)

109-117: LGTM: Added pause and unpause functions

The addition of pause and unpause functions provides important contract management capabilities. The onlyOwner modifier ensures that only the contract owner can call these functions, which is appropriate for such critical operations.

Consider emitting events when the contract is paused or unpaused for better transparency and easier off-chain tracking. For example:

function pause() external onlyOwner {
    _pause();
    emit ContractPaused(msg.sender);
}

function unpause() external onlyOwner {
    _unpause();
    emit ContractUnpaused(msg.sender);
}

Don't forget to define these events in your contract.


119-134: LGTM: Added markBootstrap functionality

The markBootstrap function and its internal implementation _markBootstrap provide a mechanism to retry bootstrap if it fails on a destination chain. The use of whenNotPaused and nonReentrant modifiers in the public function is appropriate for security.

Consider adding error handling for the _sendInterchainMsg call in the _markBootstrap function. While it's internal, it's good practice to handle potential failures, especially in cross-chain communications. For example:

function _markBootstrap(uint32 chainIndex) internal {
    try {
        _sendInterchainMsg(chainIndex, Action.REQUEST_MARK_BOOTSTRAP, "", false);
        emit BootstrapRequestSent(chainIndex);
    } catch Error(string memory reason) {
        emit BootstrapRequestFailed(chainIndex, reason);
    } catch (bytes memory lowLevelData) {
        emit BootstrapRequestFailed(chainIndex, "Low level error");
    }
}

Don't forget to define the BootstrapRequestFailed event in your contract.


242-273: LGTM: Added operator association management functions

The new functions associateOperatorWithEVMStaker and dissociateOperatorFromEVMStaker provide important functionality for managing operator associations. They are properly restricted with the whenNotPaused modifier and use custom errors consistently with the rest of the contract.

Consider emitting events when an operator is associated or dissociated for better transparency and easier off-chain tracking. For example:

function associateOperatorWithEVMStaker(uint32 clientChainId, string calldata operator)
    external
    whenNotPaused
    isValidBech32Address(operator)
{
    bytes memory staker = abi.encodePacked(bytes32(bytes20(msg.sender)));
    bool success = DELEGATION_CONTRACT.associateOperatorWithStaker(clientChainId, staker, bytes(operator));
    if (!success) {
        revert Errors.AssociateOperatorFailed(clientChainId, msg.sender, operator);
    }
    emit OperatorAssociated(clientChainId, msg.sender, operator);
}

function dissociateOperatorFromEVMStaker(uint32 clientChainId) external whenNotPaused {
    bytes memory staker = abi.encodePacked(bytes32(bytes20(msg.sender)));
    bool success = DELEGATION_CONTRACT.dissociateOperatorFromStaker(clientChainId, staker);
    if (!success) {
        revert Errors.DissociateOperatorFailed(clientChainId, msg.sender);
    }
    emit OperatorDissociated(clientChainId, msg.sender);
}

Don't forget to define these events in your contract.


312-336: LGTM: Improved _lzReceive function with enhanced security and error handling

The changes in the _lzReceive function represent significant improvements:

  1. Custom errors are now used, which is more gas-efficient.
  2. Additional checks for message length and supported requests enhance security.
  3. The use of a low-level call allows for dynamic execution of handler functions.

These modifications improve the function's efficiency, security, and flexibility.

Consider providing more detailed error information when the low-level call fails. Instead of just returning the raw responseOrReason, you could decode it if it's an error message. For example:

if (!success) {
    if (responseOrReason.length > 0) {
        // Try to decode the error message
        string memory errorMsg;
        try abi.decode(responseOrReason, (string)) returns (string memory _errorMsg) {
            errorMsg = _errorMsg;
        } catch {
            errorMsg = "Unknown error";
        }
        revert Errors.RequestOrResponseExecuteFailed(act, _origin.nonce, errorMsg);
    } else {
        revert Errors.RequestOrResponseExecuteFailed(act, _origin.nonce, "Empty error");
    }
}

This would provide more meaningful error messages when the execution fails.


338-366: LGTM: Added handleLSTTransfer function for LST operations

The new handleLSTTransfer function effectively manages Liquid Staking Token (LST) transfers, supporting both deposit and withdrawal operations. It appropriately uses the ASSETS_CONTRACT for transfer operations, emits relevant events, and sends interchain messages with the results.

Key points:

  1. Proper handling of different actions (deposit/withdrawal).
  2. Use of custom errors for failure cases.
  3. Restricted to be called only from the contract itself (onlyCalledFromThis modifier).

Consider adding error handling for the _sendInterchainMsg call at the end of the function. While it's unlikely to fail, it's good practice to handle potential errors in cross-chain communications. For example:

bytes memory response = abi.encodePacked(lzNonce, success, updatedBalance);
try {
    _sendInterchainMsg(srcChainId, Action.RESPOND, response, true);
} catch Error(string memory reason) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, reason);
} catch (bytes memory lowLevelData) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, "Low level error");
}

Don't forget to define the InterchainMessageFailed event in your contract.


369-397: LGTM: Added handleNSTTransfer function for NST operations

The new handleNSTTransfer function effectively manages Native Staking Token (NST) transfers, supporting both deposit and withdrawal operations. It's structurally similar to handleLSTTransfer but appropriately uses different ASSETS_CONTRACT functions and includes the validator's public key in the payload.

Key points:

  1. Proper handling of different actions (deposit/withdrawal).
  2. Use of custom errors for failure cases.
  3. Restricted to be called only from the contract itself (onlyCalledFromThis modifier).

As with handleLSTTransfer, consider adding error handling for the _sendInterchainMsg call at the end of the function. For example:

bytes memory response = abi.encodePacked(lzNonce, success, updatedBalance);
try {
    _sendInterchainMsg(srcChainId, Action.RESPOND, response, true);
} catch Error(string memory reason) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, reason);
} catch (bytes memory lowLevelData) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, "Low level error");
}

This ensures that any potential errors in cross-chain communication are properly handled and logged.


400-418: LGTM: Added handleRewardOperation function for reward claims

The new handleRewardOperation function effectively manages reward claim operations. It appropriately uses the CLAIM_REWARD_CONTRACT for the actual claim operation, emits relevant events, and sends interchain messages with the results.

Key points:

  1. Proper handling of the reward claim process.
  2. Use of custom errors implicitly through the CLAIM_REWARD_CONTRACT.
  3. Restricted to be called only from the contract itself (onlyCalledFromThis modifier).

As with previous functions, consider adding error handling for the _sendInterchainMsg call at the end of the function. For example:

bytes memory response = abi.encodePacked(lzNonce, success, updatedBalance);
try {
    _sendInterchainMsg(srcChainId, Action.RESPOND, response, true);
} catch Error(string memory reason) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, reason);
} catch (bytes memory lowLevelData) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, "Low level error");
}

This ensures that any potential errors in cross-chain communication are properly handled and logged.


421-446: LGTM: Added handleDelegation function for delegation operations

The new handleDelegation function effectively manages delegation and undelegation operations. It appropriately uses the DELEGATION_CONTRACT for the actual delegation operations, emits relevant events, and sends interchain messages with the results.

Key points:

  1. Proper handling of different actions (delegate/undelegate).
  2. Use of custom errors implicitly through the DELEGATION_CONTRACT.
  3. Restricted to be called only from the contract itself (onlyCalledFromThis modifier).

As with previous functions, consider adding error handling for the _sendInterchainMsg call at the end of the function. For example:

bytes memory response = abi.encodePacked(lzNonce, accepted);
try {
    _sendInterchainMsg(srcChainId, Action.RESPOND, response, true);
} catch Error(string memory reason) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, reason);
} catch (bytes memory lowLevelData) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, "Low level error");
}

This ensures that any potential errors in cross-chain communication are properly handled and logged.


449-473: LGTM: Added handleDepositAndDelegate function for combined operations

The new handleDepositAndDelegate function effectively manages a combined deposit and delegate operation. It appropriately uses both ASSETS_CONTRACT and DELEGATION_CONTRACT, emits relevant events for both deposit and delegation operations, and sends an interchain message with the results.

Key points:

  1. Proper handling of the combined deposit and delegate operation.
  2. Use of custom errors for failure cases.
  3. Restricted to be called only from the contract itself (onlyCalledFromThis modifier).

As with previous functions, consider adding error handling for the _sendInterchainMsg call at the end of the function. For example:

bytes memory response = abi.encodePacked(lzNonce, accepted, updatedBalance);
try {
    _sendInterchainMsg(srcChainId, Action.RESPOND, response, true);
} catch Error(string memory reason) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, reason);
} catch (bytes memory lowLevelData) {
    emit InterchainMessageFailed(srcChainId, Action.RESPOND, "Low level error");
}

This ensures that any potential errors in cross-chain communication are properly handled and logged.


Line range hint 1-538: Overall assessment: Significant improvements and additions to ExocoreGatewayMock

This update to the ExocoreGatewayMock contract introduces several important improvements and new functionalities:

  1. Enhanced error handling using custom errors throughout the contract, improving gas efficiency and error reporting.
  2. New handler functions for various operations (LST/NST transfers, rewards, delegations, operator associations), expanding the contract's capabilities.
  3. Improved security measures, including the use of ReentrancyGuard and additional checks in critical functions.
  4. Consistent use of access control modifiers (onlyOwner, onlyCalledFromThis, whenNotPaused) across new and modified functions.

The changes are well-structured and maintain consistency with the existing code. The new functionalities align with the contract's purpose as a mock for the ExocoreGateway.

Consider implementing the suggested improvements in error handling for cross-chain message sending (_sendInterchainMsg) in the various handler functions. This would further enhance the contract's robustness and error reporting capabilities.

As the contract grows in complexity, consider breaking it down into smaller, more focused contracts using inheritance or a modular design pattern. This could improve maintainability and make it easier to test individual components.

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 58832f0 and e18a666.

Files selected for processing (8)
  • docs/native_deposit_workflow.wsd (1 hunks)
  • src/core/ExocoreGateway.sol (5 hunks)
  • src/libraries/Errors.sol (6 hunks)
  • src/storage/BootstrapStorage.sol (3 hunks)
  • src/storage/ClientChainGatewayStorage.sol (3 hunks)
  • src/storage/ExocoreGatewayStorage.sol (2 hunks)
  • test/foundry/unit/ClientChainGateway.t.sol (6 hunks)
  • test/mocks/ExocoreGatewayMock.sol (10 hunks)
Files skipped from review due to trivial changes (1)
  • docs/native_deposit_workflow.wsd
Files skipped from review as they are similar to previous changes (2)
  • src/storage/ClientChainGatewayStorage.sol
  • test/foundry/unit/ClientChainGateway.t.sol
Additional context used
Learnings (2)
src/core/ExocoreGateway.sol (2)
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:305-306
Timestamp: 2024-09-23T09:39:44.021Z
Learning: Within `ExocoreGateway.sol`, the `_validateMessageLength` function ensures that `message` has sufficient length, so additional length checks after calling `_validateMessageLength` are unnecessary.
Learnt from: MaxMustermann2
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:340-341
Timestamp: 2024-09-22T10:48:21.801Z
Learning: In `ExocoreGateway`, the payload length is validated in `_lzReceive`, so additional checks in functions like `handleLSTTransfer` are unnecessary.
test/mocks/ExocoreGatewayMock.sol (2)
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/ExocoreGatewayMock.sol:338-366
Timestamp: 2024-09-23T09:39:05.445Z
Learning: In the `ExocoreGateway`, deposit operations are intended to be must-succeed and should revert on failure, while withdrawal failures are acceptable and should not trigger a revert.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/ExocoreGatewayMock.sol:144-149
Timestamp: 2024-09-23T09:40:29.126Z
Learning: When reviewing mock contracts, optimizations for error handling are not necessary.
Additional comments not posted (25)
src/storage/ExocoreGatewayStorage.sol (8)

4-6: LGTM: New imports align with PR objectives

The new imports for ActionAttributes, Errors, and Action libraries are appropriate for the changes made in the contract. They support the handling of different message types and improved error handling, which aligns with the PR objectives.


13-13: LGTM: ActionAttributes usage supports new message handling

The addition of using ActionAttributes for Action; is consistent with the new imports and supports the new message handling approach mentioned in the PR objectives.


46-52: LGTM: Improved ClaimRewardResult event

The updated ClaimRewardResult event now includes a 'success' parameter, which enhances the informativeness of the event. This change is consistent with the PR's goal of improving clarity in operations.


54-61: LGTM: New LSTTransfer event aligns with PR objectives

The new LSTTransfer event is well-structured and provides comprehensive information about Liquid Staking Token transfers. It includes parameters for deposit/withdraw operations, success status, token, staker, and amount. This event aligns perfectly with the PR objective of separating LST operations and enhances the contract's ability to track and report on these transfers.


64-71: LGTM: New NSTTransfer event supports NST operations and oracle functionality

The new NSTTransfer event is well-designed and crucial for tracking Native Staking Token transfers. It includes essential parameters such as deposit/withdraw flag, success status, validator public key, staker, and amount. This event aligns perfectly with the PR objective of separating NST operations and supports the oracle module's functionality by including the validator public key. The structure is consistent with best practices and complements the LSTTransfer event.


74-87: LGTM: Consolidated DelegationRequest event improves efficiency

The updated DelegationRequest event efficiently consolidates both delegate and undelegate operations into a single event. It provides comprehensive information about delegation requests, including the operation type, acceptance status, token, delegator, operator, and amount. This consolidation simplifies event handling and aligns with the PR's goal of improving code organization and efficiency.


103-121: LGTM: New _validateMessageLength function enhances message handling robustness

The new _validateMessageLength function is a valuable addition that enhances the robustness of message handling in the contract. It effectively uses the Action enum and ActionAttributes library to validate message lengths based on action types. The function includes appropriate error handling for invalid message lengths and unsupported requests, consistent with the new Errors library. This implementation aligns well with the PR objective of improving code organization and supporting different message types.


Line range hint 1-122: Overall: Excellent refactoring that aligns with PR objectives

The changes in this file successfully achieve the PR's objectives of separating NST and LST operations, improving code organization, and enhancing message handling. Key improvements include:

  1. New events (LSTTransfer and NSTTransfer) that clearly distinguish between LST and NST operations.
  2. Updated DelegationRequest event that consolidates delegation-related operations.
  3. New _validateMessageLength function that improves message handling robustness.
  4. Appropriate use of new libraries (ActionAttributes, Errors) to support these changes.

These modifications contribute to a more modular, clear, and efficient contract structure, which will facilitate the updating of beacon chain balances by the oracle module as intended.

src/libraries/Errors.sol (8)

Line range hint 4-57: LGTM: New errors for cross-chain communication

The new import and error definitions (UnsupportedRequest, UnexpectedSourceChain, UnexpectedInboundNonce) are well-documented and align with the PR objectives. They provide clear error handling for cross-chain communication scenarios, which is crucial for the separation of NST and LST messages.


159-160: LGTM: CapsuleDoesNotExist error

The CapsuleDoesNotExist error is a clear and concise addition that aligns with the library's naming conventions and the PR objectives. It will be useful for handling ExoCapsule-related operations.


169-186: LGTM: New errors for response handling and whitelist operations

The new errors (UnsupportedResponse, UnexpectedResponse, DepositShouldNotFailOnExocore, and InvalidAddWhitelistTokensRequest) are well-documented and provide clear error handling for various scenarios. They align with the PR objectives, particularly in improving the handling of cross-chain responses and deposit operations.


188-191: LGTM: WithdrawFailedOnExocore event

The WithdrawFailedOnExocore event is a valuable addition for tracking and debugging withdrawal failures. It's well-documented and uses indexed parameters appropriately, which will facilitate efficient event filtering and monitoring of withdrawal issues on the Exocore side.


238-245: LGTM: New errors for precompile calls and message validation

The PrecompileCallFailed and InvalidMessageLength errors are well-defined and provide clear error handling for precompile call failures and message length validation, respectively. These additions will improve the robustness of cross-chain message processing in the Exocore system.


252-254: LGTM: RegisterClientChainToExocoreFailed error

The RegisterClientChainToExocoreFailed error is a clear and useful addition for handling failed client chain registrations. The inclusion of the clientChainId parameter will greatly assist in debugging and troubleshooting cross-chain registration issues.


256-264: LGTM: New errors for whitelist token operations

The AddWhitelistTokenFailed and UpdateWhitelistTokenFailed errors are well-defined and provide clear error handling for whitelist token operations. The inclusion of clientChainId and token parameters will be valuable for debugging cross-chain token management issues. These additions align well with the PR objectives for separating NST and LST operations.


Line range hint 1-301: LGTM: Comprehensive error handling for Exocore operations

The Errors.sol file has been updated with a comprehensive set of new errors that align well with the PR objectives. The additions provide robust error handling for cross-chain operations, token management, and ExoCapsule interactions. The file maintains a consistent structure and naming convention, making it easy to navigate and understand.

The new errors and event cover various scenarios that may occur during the separation of NST and LST operations, which will greatly improve the system's ability to handle and report issues. This comprehensive approach to error handling will enhance the overall reliability and debuggability of the Exocore system.

src/storage/BootstrapStorage.sol (2)

129-130: LGTM: Addition of VIRTUAL_NST_ADDRESS constant

The introduction of VIRTUAL_NST_ADDRESS aligns with the PR's objective to separate Native Staking Token (NST) operations. Using a virtual address (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) for native tokens is a common and recognized practice in Ethereum-based systems, enhancing the contract's ability to handle native token operations consistently.


Line range hint 1-365: Summary: Improvements in NST handling and error management

The changes in this file successfully contribute to the PR's objective of separating Native Staking Token (NST) operations from Liquid Staking Token (LST) operations. The introduction of VIRTUAL_NST_ADDRESS, prevention of vault deployment for NST, and improved error handling enhance the contract's ability to manage different token types more effectively.

These modifications improve code quality, maintainability, and align with best practices in Solidity development. The suggested minor improvements in error messaging could further enhance debugging and code clarity.

test/mocks/ExocoreGatewayMock.sol (6)

4-4: LGTM: Import statement for Action

The addition of this import statement is appropriate for the new functionality using the Action enum.


81-92: LGTM: Improved initialization with custom error and ReentrancyGuard

The changes in the initialize function are positive:

  1. Using a custom error (Errors.ZeroAddress()) for the zero address check is more gas-efficient.
  2. The addition of __ReentrancyGuard_init_unchained() enhances the contract's security against reentrancy attacks.

These modifications improve both efficiency and security.


95-106: LGTM: Updated whitelist function selectors

The _initializeWhitelistFunctionSelectors function has been expanded to include selectors for new operations such as LST and NST transfers, reward operations, delegation, and operator association. These additions are consistent with the new functions implemented in the contract and are necessary for the gateway's functionality.


Line range hint 135-240: LGTM: Improved error handling and security in client chain and token management functions

The changes in registerOrUpdateClientChain, setPeer, addWhitelistToken, and updateWhitelistToken functions represent significant improvements:

  1. Custom errors are now used instead of require statements, which is more gas-efficient.
  2. The setPeer function now includes a check for registered client chain ID, enhancing security.
  3. Error handling in addWhitelistToken and updateWhitelistToken is improved with custom errors.

These modifications enhance the contract's efficiency, readability, and security while maintaining the core functionality of each function.


Line range hint 275-309: LGTM: Added internal functions for client chain validation and management

The new internal functions _validateClientChainIdRegistered and _registerOrUpdateClientChain provide important utility for client chain management:

  1. _validateClientChainIdRegistered ensures that a given client chain ID is registered, using the ASSETS_CONTRACT.
  2. _registerOrUpdateClientChain handles the registration or update of a client chain, also using the ASSETS_CONTRACT.

Both functions use custom errors consistently with the rest of the contract and properly handle success and failure cases. These additions enhance the contract's ability to manage client chains effectively and securely.


476-498: LGTM: Added handleOperatorAssociation function for operator management

The new handleOperatorAssociation function effectively manages the association and dissociation of operators. It appropriately uses the DELEGATION_CONTRACT for the actual operations and emits an event with the result.

Key points:

  1. Proper handling of different actions (associate/dissociate).
  2. Use of custom errors implicitly through the DELEGATION_CONTRACT.
  3. Restricted to be called only from the contract itself (onlyCalledFromThis modifier).
  4. Consistent with other handler functions in the contract.

This function enhances the contract's ability to manage operator associations effectively and securely.

src/core/ExocoreGateway.sol (1)

372-374: Correct the extraction of validatorPubkey; expected length may be incorrect

In the handleNSTTransfer function, validatorPubkey is extracted using payload[:32]. However, Ethereum BLS validator public keys are typically 48 bytes in length. Extracting only 32 bytes may result in incomplete or invalid public keys.

Ensure that the validatorPubkey is correctly extracted with the appropriate length. If the public key is 48 bytes, adjust the slicing accordingly:

- bytes calldata validatorPubkey = payload[:32];
- bytes calldata staker = payload[32:64];
- uint256 amount = uint256(bytes32(payload[64:96]));
+ bytes calldata validatorPubkey = payload[:48];
+ bytes calldata staker = payload[48:80];
+ uint256 amount = uint256(bytes32(payload[80:112]));

Make sure to update all subsequent offsets and ensure that the payload being sent matches this structure. This adjustment will correctly parse the validatorPubkey, staker, and amount from the payload.

Skipped due to learnings
Learnt from: bwhour
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/AssetsMock.sol:75-90
Timestamp: 2024-09-21T06:01:54.422Z
Learning: In the `withdrawNST` function of `AssetsMock.sol`, the `validatorPubkey.length` should be 32 bytes, not 48 bytes.

src/core/ExocoreGateway.sol Show resolved Hide resolved
src/core/ExocoreGateway.sol Show resolved Hide resolved
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

Outside diff range and nitpick comments (1)
src/storage/ExocoreGatewayStorage.sol (1)

104-122: LGTM: Robust message length validation

The _validateMessageLength function provides a centralized and robust way to validate message lengths. It effectively uses the new Action enum and ActionAttributes library, with appropriate error handling using custom errors from the Errors library. This aligns well with the PR objective of improving message validation.

Consider adding a comment explaining the significance of the expectedLength == 0 check:

 if (expectedLength == 0) {
+    // expectedLength of 0 indicates an unsupported action
     revert Errors.UnsupportedRequest(action);
 }
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 58832f0 and 8a86625.

Files selected for processing (8)
  • docs/native_deposit_workflow.wsd (1 hunks)
  • src/core/ExocoreGateway.sol (5 hunks)
  • src/libraries/Errors.sol (6 hunks)
  • src/storage/BootstrapStorage.sol (3 hunks)
  • src/storage/ClientChainGatewayStorage.sol (3 hunks)
  • src/storage/ExocoreGatewayStorage.sol (2 hunks)
  • test/foundry/unit/ClientChainGateway.t.sol (6 hunks)
  • test/mocks/ExocoreGatewayMock.sol (10 hunks)
Files skipped from review as they are similar to previous changes (4)
  • docs/native_deposit_workflow.wsd
  • src/storage/BootstrapStorage.sol
  • src/storage/ClientChainGatewayStorage.sol
  • test/foundry/unit/ClientChainGateway.t.sol
Additional context used
Learnings (2)
src/core/ExocoreGateway.sol (4)
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:313-315
Timestamp: 2024-09-23T10:03:22.440Z
Learning: When using `address(this).call(...)`, `msg.sender` becomes `address(this)`, so functions with the `onlyCalledFromThis` modifier will function correctly.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:425-438
Timestamp: 2024-09-23T10:01:38.842Z
Learning: In the `handleDelegation` function of `ExocoreGateway.sol`, the `operator` variable is converted from a string, so casting from `bytes` to `string` is safe because `operator` will always contain valid UTF-8 encoded characters.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:305-306
Timestamp: 2024-09-23T09:39:44.021Z
Learning: Within `ExocoreGateway.sol`, the `_validateMessageLength` function ensures that `message` has sufficient length, so additional length checks after calling `_validateMessageLength` are unnecessary.
Learnt from: MaxMustermann2
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:340-341
Timestamp: 2024-09-22T10:48:21.801Z
Learning: In `ExocoreGateway`, the payload length is validated in `_lzReceive`, so additional checks in functions like `handleLSTTransfer` are unnecessary.
test/mocks/ExocoreGatewayMock.sol (2)
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/ExocoreGatewayMock.sol:338-366
Timestamp: 2024-09-23T09:39:05.445Z
Learning: In the `ExocoreGateway`, deposit operations are intended to be must-succeed and should revert on failure, while withdrawal failures are acceptable and should not trigger a revert.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/ExocoreGatewayMock.sol:144-149
Timestamp: 2024-09-23T09:40:29.126Z
Learning: When reviewing mock contracts, optimizations for error handling are not necessary.
Additional comments not posted (31)
src/storage/ExocoreGatewayStorage.sol (7)

4-6: LGTM: New imports align with contract changes

The new imports for ActionAttributes, Errors, and Action libraries are appropriate and necessary for the new functionality introduced in the contract.


13-13: LGTM: Appropriate library usage

The using ActionAttributes for Action; statement is consistent with the new imports and supports the new message length validation functionality.


46-52: LGTM: Well-defined ClaimRewardResult event

The ClaimRewardResult event is well-structured and provides necessary information for tracking reward withdrawals. The parameter descriptions are clear and accurate.


54-61: LGTM: Well-structured LSTTransfer event

The LSTTransfer event is well-designed and aligns with the PR objective of separating LST operations. It efficiently handles both deposit and withdrawal operations, providing clear and accurate parameter descriptions.


64-71: LGTM: Well-defined NSTTransfer event

The NSTTransfer event is well-structured and aligns with the PR objective of separating NST operations. The inclusion of the validator public key supports the requirement mentioned in the PR objectives. The parameter descriptions are clear and accurate.


74-88: LGTM: Comprehensive DelegationRequest event

The DelegationRequest event is well-designed and provides comprehensive information about delegation requests. It efficiently handles both delegate and undelegate operations, with clear and accurate parameter descriptions.


Line range hint 1-123: Overall: Excellent refactoring and improvements

This refactoring successfully separates NST and LST operations, improves message validation, and supports sending validator public keys to Exocore. The new events and internal function are well-designed and align perfectly with the PR objectives. The code is clean, well-documented, and follows best practices.

Great job on this refactoring effort!

src/libraries/Errors.sol (15)

4-5: LGTM: Import statement for Action

The import statement for Action from GatewayStorage.sol is correctly added and necessary for the new error definitions.


46-49: LGTM: UnsupportedRequest error

The UnsupportedRequest error is well-defined and properly documented. It follows the established pattern for error definitions in this library.


50-53: LGTM: UnexpectedSourceChain error

The UnexpectedSourceChain error is well-defined and properly documented. The use of uint32 for the chain ID is appropriate.


54-57: LGTM: UnexpectedInboundNonce error

The UnexpectedInboundNonce error is well-defined and properly documented. The use of uint64 for nonces is appropriate and provides a good balance between range and gas efficiency.


126-127: LGTM: VaultDoesNotExist error

The VaultDoesNotExist error is concise and follows the established naming convention. It's consistent with similar errors in the library.


129-130: LGTM: NotYetSupported error

The NotYetSupported error is concise and self-explanatory. It's a useful error for features that are planned but not yet implemented.


132-138: LGTM: RequestOrResponseExecuteFailed error

The RequestOrResponseExecuteFailed error is well-defined and thoroughly documented. The use of bytes for the reason parameter allows for flexible and detailed error messages.


159-160: LGTM: CapsuleDoesNotExist error

The CapsuleDoesNotExist error is concise and follows the established naming convention. It's consistent with the VaultDoesNotExist error, maintaining a coherent error handling approach.


169-176: LGTM: UnsupportedResponse and UnexpectedResponse errors

Both UnsupportedResponse and UnexpectedResponse errors are well-defined and properly documented. They complement the existing UnsupportedRequest error, providing a symmetrical approach to error handling for both requests and responses.


178-186: LGTM: DepositShouldNotFailOnExocore and InvalidAddWhitelistTokensRequest errors

Both DepositShouldNotFailOnExocore and InvalidAddWhitelistTokensRequest errors are well-defined and properly documented. The InvalidAddWhitelistTokensRequest error includes both expected and actual lengths, which is particularly helpful for debugging purposes.


188-191: LGTM: WithdrawFailedOnExocore event

The WithdrawFailedOnExocore event is well-defined and properly documented. The use of indexed parameters for token and withdrawer allows for efficient event filtering, which is a good practice.


238-250: LGTM: PrecompileCallFailed, InvalidMessageLength, and DepositRequestShouldNotFail errors

All three errors (PrecompileCallFailed, InvalidMessageLength, and DepositRequestShouldNotFail) are well-defined and properly documented. The PrecompileCallFailed error includes both the selector and reason, which is particularly helpful for debugging. The comment indicating that DepositRequestShouldNotFail is a critical error is valuable information for error handling.


252-264: LGTM: Client chain and whitelist token operation errors

The errors RegisterClientChainToExocoreFailed, AddWhitelistTokenFailed, and UpdateWhitelistTokenFailed are well-defined and properly documented. They provide specific error cases for client chain registration and whitelist token operations, which will be helpful for debugging and error handling in these processes.


266-270: LGTM: Whitelist token input validation errors

The errors InvalidWhitelistTokensInput and WhitelistTokensListTooLong are well-defined and properly documented. They provide specific error cases for input validation of whitelist tokens, which will be helpful for ensuring the integrity of whitelist token operations.


Line range hint 1-301: Overall assessment: Excellent additions to the Errors library

The new errors and event added to the Errors.sol library are well-defined, properly documented, and consistent with the existing code style. These additions enhance the error handling capabilities of the Exocore contracts by providing more specific and detailed error information. This will significantly aid in debugging and development processes.

Some notable improvements:

  1. Consistent naming conventions and documentation styles.
  2. Appropriate use of parameter types (e.g., uint32 for chain IDs, uint64 for nonces).
  3. Inclusion of both generic (e.g., NotYetSupported) and specific (e.g., DepositShouldNotFailOnExocore) error types.
  4. Addition of the WithdrawFailedOnExocore event with indexed parameters for efficient filtering.

These changes contribute to a more robust and developer-friendly error handling system for the Exocore contracts.

src/core/ExocoreGateway.sol (5)

6-11: Imports are correctly added and organized

The new imports for Errors, Action, and the precompile interfaces are appropriately added, ensuring that the contract has access to the necessary external contracts and libraries.


80-89: Whitelist function selectors are properly initialized

The mapping of action enums to their respective handler function selectors in _initializeWhitelistFunctionSelectors is correctly implemented, allowing for accurate dispatching of incoming messages based on the action type.


295-324: Message handling logic is well-structured and secure

The _lzReceive function accurately processes incoming messages, validates them, and dispatches to the appropriate handlers using address(this).call(). The use of onlyCalledFromThis modifier ensures internal security when invoking handler functions.


425-438: Efficient handling of delegation requests

The handleDelegation function correctly processes delegation and undelegation requests, safely casting operator from bytes to string. This is acceptable as per prior learning that operator contains valid UTF-8 encoded characters.


478-492: Potential mismatch in operator data slicing

In handleOperatorAssociation, the operator is sliced from payload[32:74], resulting in 42 bytes. Ensure that this length aligns with the expected size of the operator data. Be cautious of potential issues if operator is of variable length.

Run the following script to verify the expected operator length:

This script extracts the end index of the operator slice to confirm it matches the expected length.

Verification successful

Operator data slicing length is correct

The operator slice length of 42 bytes in handleOperatorAssociation aligns with the expected operator data size.

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the length of operator data used in handleOperatorAssociation.

# Test: Ensure operator data length is consistent.
# Expect: Operator data should be of expected length.

rg --type solidity 'handleOperatorAssociation' -A 10 | rg 'operator = payload\[32:([0-9]+)\];' -o -r '$1'

Length of output: 138


Script:

#!/bin/bash
# Description: Check the length of operator data used in handleOperatorAssociation.

# Test: Ensure operator data length is consistent.
# Expect: Operator data should be of expected length.

rg 'handleOperatorAssociation' -A 10 -g '*.sol' | rg 'operator = payload\[32:([0-9]+)\];' -o -r '$1'

Length of output: 106

test/mocks/ExocoreGatewayMock.sol (4)

84-86: Good addition: Zero address check for owner_ in initialize

Adding a check to prevent a zero address for owner_ in the initialize function enhances the contract's security during initialization.


97-106: Function selectors are correctly mapped to actions

The initialization of the _whiteListFunctionSelectors mapping correctly associates each Action with its corresponding handler function, ensuring that incoming messages are handled appropriately.


320-320: Improved robustness with message length validation

Including _validateMessageLength(message); in the _lzReceive function enhances the robustness by ensuring that the message meets expected length requirements before processing.


255-256: Verify correct encoding of staker address

Please verify that the staker's address is correctly encoded when calling DELEGATION_CONTRACT.associateOperatorWithStaker and DELEGATION_CONTRACT.dissociateOperatorFromStaker. The use of abi.encodePacked(bytes32(bytes20(msg.sender))) may introduce unnecessary padding. Consider using abi.encodePacked(msg.sender) if the receiving function expects the address in this format.

Run the following script to check for consistent staker address encoding:

Also applies to: 268-269

src/core/ExocoreGateway.sol Show resolved Hide resolved
src/core/ExocoreGateway.sol Show resolved Hide resolved
test/mocks/ExocoreGatewayMock.sol Show resolved Hide resolved
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

Outside diff range and nitpick comments (9)
src/storage/GatewayStorage.sol (2)

7-21: Expanded Action enum enhances functionality.

The Action enum has been significantly expanded to include a wider range of operations, including separate actions for NST and LST deposits/withdrawals, reward claiming, delegation, and system management. This aligns well with the PR objectives and suggests a more comprehensive approach to handling various operations within the system.

Consider adding inline documentation for each enum value to clarify their specific purposes and use cases. This would greatly enhance the readability and maintainability of the code. For example:

enum Action {
    /// @notice Request to deposit Liquid Staking Tokens
    REQUEST_DEPOSIT_LST,
    /// @notice Request to deposit Native Staking Tokens
    REQUEST_DEPOSIT_NST,
    // ... (continue for each enum value)
}

Missing payload length validation after removal of _validatePayloadLength.

The removal of the _validatePayloadLength function appears to leave the contract without necessary payload length checks, potentially compromising security. Ensure that payload validation is properly implemented elsewhere in the contract to maintain robust security measures.

Analysis chain

Line range hint 1-90: Clarification needed on payload validation after removal of _validatePayloadLength.

The summary indicates that the _validatePayloadLength function has been removed. This function was likely responsible for ensuring that incoming payloads met certain length requirements, which is an important security measure.

Could you please clarify how payload validation is now being handled? It's crucial to ensure that this security check hasn't been overlooked. If it's been moved to another part of the codebase, please provide details on its new location and implementation.

To help verify this, let's search for any new payload validation logic:

Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for new payload validation logic

# Test 1: Look for functions or methods that might be handling payload validation
echo "Searching for potential payload validation logic:"
rg "function.*payload" --type solidity
rg "function.*validate" --type solidity

# Test 2: Check for any length checks that might be related to payload validation
echo "Checking for length validations:"
rg "\.length\s*(==|!=|>|<|>=|<=)" --type solidity

Length of output: 417


Script:

#!/bin/bash
# Description: Search for new payload validation logic in Solidity files

# Test 1: Look for functions or methods that might be handling payload validation
echo "Searching for potential payload validation logic in .sol files:"
rg "function.*payload" --glob "*.sol"
rg "function.*validate" --glob "*.sol"

# Test 2: Check for any length checks that might be related to payload validation
echo "Checking for length validations in .sol files:"
rg "\.length\s*(==|!=|>|<|>=|<=)" --glob "*.sol"

Length of output: 14023


Script:

#!/bin/bash
# Description: Further search for payload length validation logic in Solidity files

# Test 1: Look for functions that explicitly validate payload length
echo "Searching for explicit payload length validation functions in .sol files:"
rg "function.*validate.*payload.*length" --glob "*.sol"
rg "function.*check.*payload.*length" --glob "*.sol"

# Test 2: Look for modifiers that might handle payload validation
echo "Searching for modifiers handling payload validation in .sol files:"
rg "modifier.*validate.*payload" --glob "*.sol"

# Test 3: Search for utility libraries or contracts that might contain payload validation logic
echo "Searching for utility contracts or libraries related to payload validation in .sol files:"
rg "library.*.*payload" --glob "*.sol"
rg "contract.*.*payload" --glob "*.sol"

Length of output: 944

src/storage/ExocoreGatewayStorage.sol (1)

104-122: Robust message length validation with a suggestion

The new _validateMessageLength function significantly enhances the contract's robustness by validating incoming messages based on their action type. The use of custom errors improves gas efficiency and error reporting. The function's design, leveraging the ActionAttributes library, is well-structured and maintainable.

Suggestion for improvement:

Consider adding a custom error for the case when message.length < 1 to provide more specific error information. This could be implemented as follows:

 function _validateMessageLength(bytes calldata message) internal pure {
     if (message.length < 1) {
-        revert Errors.InvalidMessageLength();
+        revert Errors.EmptyMessage();
     }
     // ... rest of the function
 }

This change would require adding a new custom error EmptyMessage() to the Errors library.

src/core/ClientGatewayLzReceiver.sol (5)

31-40: New nextNonce function implementation

The addition of the nextNonce function is a good implementation that correctly calculates the next nonce. The virtual modifier allows for potential customization in derived contracts.

Consider adding a brief comment explaining the purpose of this function and why it's overriding the base implementation.

 /// @inheritdoc OAppReceiverUpgradeable
+/// @dev Overrides the base implementation to provide custom nonce calculation
 function nextNonce(uint32 srcEid, bytes32 sender)
     public
     view
     virtual
     override(OAppReceiverUpgradeable)
     returns (uint64)
 {
     return inboundNonce[srcEid][sender] + 1;
 }

45-67: Improved _lzReceive function with better error handling and action processing

The refactoring of the _lzReceive function significantly improves its clarity and robustness. The use of the Errors library enhances error handling consistency, and the explicit handling of different action types improves the separation of concerns.

Consider adding a comment explaining the purpose of the _whiteListFunctionSelectors mapping and how it's used to determine the appropriate function to call for each action type.

 Action act = Action(uint8(message[0]));
 bytes calldata payload = message[1:];
 if (act == Action.RESPOND) {
     _handleResponse(message);
 } else {
+    // _whiteListFunctionSelectors maps actions to their corresponding function selectors
     bytes4 selector_ = _whiteListFunctionSelectors[act];
     if (selector_ == bytes4(0)) {
         revert Errors.UnsupportedRequest(act);
     }

     (bool success, bytes memory reason) = address(this).call(abi.encodePacked(selector_, abi.encode(payload)));
     if (!success) {
         revert Errors.RequestOrResponseExecuteFailed(act, _origin.nonce, reason);
     }
 }

Line range hint 71-100: Improved _handleResponse function with better modularity and withdrawal handling

The refactoring of the _handleResponse function significantly improves its clarity and modularity. The function now focuses explicitly on withdrawal actions and uses helper functions for updating balances, which enhances code organization. The separate handling of principal and reward withdrawals improves the function's flexibility.

Consider adding a comment explaining the purpose of the _getCachedRequestForResponse function and how it relates to the overall request-response flow.

+// Retrieve the cached request details for the incoming response
 (uint64 requestId, Action requestAct, bytes memory cachedRequest) = _getCachedRequestForResponse(response);

 if (!requestAct.isWithdrawal()) {
     revert Errors.UnsupportedResponse(requestAct);
 }

 bool requestSuccess = _isSuccess(response);
 if (requestSuccess) {
     (address token, address staker, uint256 amount) = _decodeCachedRequest(cachedRequest);

     if (requestAct.isPrincipal()) {
         _updatePrincipalWithdrawableBalance(token, staker, amount);
     } else if (requestAct.isReward()) {
         _updateRewardWithdrawableBalance(token, staker, amount);
     } else {
         revert Errors.UnsupportedResponse(requestAct);
     }
 }

129-135: Simplified _decodeCachedRequest function

The _decodeCachedRequest function has been simplified, improving its readability and efficiency. The direct use of abi.decode to extract all values at once is a good practice.

Consider adding a comment to explain the expected structure of the cached request, as this function now assumes a specific format.

 function _decodeCachedRequest(bytes memory cachedRequest)
     internal
     pure
     returns (address token, address staker, uint256 amount)
 {
+    // Cached request structure: (address token, address staker, uint256 amount)
     return abi.decode(cachedRequest, (address, address, uint256));
 }

146-171: New helper functions for updating withdrawable balances

The addition of _updatePrincipalWithdrawableBalance and _updateRewardWithdrawableBalance functions improves code modularity and readability. These functions provide a clear separation of concerns for handling different types of withdrawals (principal and reward) and interact appropriately with the relevant contracts (ExoCapsule or Vault).

Consider adding error handling for the case where an invalid token address is provided, especially in the _updatePrincipalWithdrawableBalance function.

 function _updatePrincipalWithdrawableBalance(address token, address staker, uint256 amount) internal {
     if (token == VIRTUAL_NST_ADDRESS) {
         IExoCapsule capsule = _getCapsule(staker);
         capsule.updateWithdrawableBalance(amount);
-    } else {
+    } else if (token != address(0)) {
         IVault vault = _getVault(token);
         vault.updateWithdrawableBalance(staker, amount, 0);
+    } else {
+        revert Errors.InvalidTokenAddress();
     }
 }
test/mocks/ExocoreGatewayMock.sol (1)

524-524: Nitpick: Inconsistent parameter naming in quote function

The parameter srcChainid should be renamed to srcChainId to maintain consistency with the naming convention used throughout the codebase.

Apply this diff to correct the parameter name:

-        function quote(uint32 srcChainid, bytes calldata _message) public view returns (uint256 nativeFee) {
+        function quote(uint32 srcChainId, bytes calldata _message) public view returns (uint256 nativeFee) {
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 8a86625 and 3a52726.

Files selected for processing (44)
  • docs/native_deposit_workflow.wsd (1 hunks)
  • script/11_SetPeers.s.sol (2 hunks)
  • script/13_DepositValidator.s.sol (2 hunks)
  • script/3_Setup.s.sol (2 hunks)
  • script/4_Deposit.s.sol (2 hunks)
  • script/5_Withdraw.s.sol (2 hunks)
  • script/TestPrecompileErrorFixed.s.sol (3 hunks)
  • script/TestPrecompileErrorFixed_Deploy.s.sol (1 hunks)
  • src/core/BaseRestakingController.sol (4 hunks)
  • src/core/Bootstrap.sol (4 hunks)
  • src/core/BootstrapLzReceiver.sol (3 hunks)
  • src/core/ClientChainGateway.sol (2 hunks)
  • src/core/ClientGatewayLzReceiver.sol (5 hunks)
  • src/core/ExoCapsule.sol (0 hunks)
  • src/core/ExocoreGateway.sol (5 hunks)
  • src/core/LSTRestakingController.sol (5 hunks)
  • src/core/NativeRestakingController.sol (4 hunks)
  • src/core/Vault.sol (0 hunks)
  • src/interfaces/IExoCapsule.sol (0 hunks)
  • src/interfaces/IVault.sol (0 hunks)
  • src/interfaces/precompiles/IAssets.sol (2 hunks)
  • src/interfaces/precompiles/IClaimReward.sol (1 hunks)
  • src/interfaces/precompiles/IDelegation.sol (4 hunks)
  • src/libraries/ActionAttributes.sol (1 hunks)
  • src/libraries/Errors.sol (6 hunks)
  • src/storage/BootstrapStorage.sol (3 hunks)
  • src/storage/ClientChainGatewayStorage.sol (3 hunks)
  • src/storage/ExoCapsuleStorage.sol (0 hunks)
  • src/storage/ExocoreGatewayStorage.sol (2 hunks)
  • src/storage/GatewayStorage.sol (2 hunks)
  • src/storage/VaultStorage.sol (0 hunks)
  • test/foundry/Delegation.t.sol (8 hunks)
  • test/foundry/DepositThenDelegateTo.t.sol (9 hunks)
  • test/foundry/DepositWithdrawPrinciple.t.sol (27 hunks)
  • test/foundry/ExocoreDeployer.t.sol (7 hunks)
  • test/foundry/WithdrawReward.t.sol (7 hunks)
  • test/foundry/unit/Bootstrap.t.sol (2 hunks)
  • test/foundry/unit/ClientChainGateway.t.sol (6 hunks)
  • test/foundry/unit/ExocoreGateway.t.sol (13 hunks)
  • test/mocks/AssetsMock.sol (2 hunks)
  • test/mocks/ClaimRewardMock.sol (1 hunks)
  • test/mocks/DelegationMock.sol (5 hunks)
  • test/mocks/ExocoreGatewayMock.sol (10 hunks)
  • test/mocks/PrecompileCallerMock.sol (1 hunks)
Files not reviewed due to no reviewable changes (6)
  • src/core/ExoCapsule.sol
  • src/core/Vault.sol
  • src/interfaces/IExoCapsule.sol
  • src/interfaces/IVault.sol
  • src/storage/ExoCapsuleStorage.sol
  • src/storage/VaultStorage.sol
Files skipped from review as they are similar to previous changes (30)
  • docs/native_deposit_workflow.wsd
  • script/11_SetPeers.s.sol
  • script/13_DepositValidator.s.sol
  • script/3_Setup.s.sol
  • script/4_Deposit.s.sol
  • script/5_Withdraw.s.sol
  • script/TestPrecompileErrorFixed.s.sol
  • script/TestPrecompileErrorFixed_Deploy.s.sol
  • src/core/BaseRestakingController.sol
  • src/core/Bootstrap.sol
  • src/core/BootstrapLzReceiver.sol
  • src/core/ClientChainGateway.sol
  • src/core/LSTRestakingController.sol
  • src/core/NativeRestakingController.sol
  • src/interfaces/precompiles/IAssets.sol
  • src/interfaces/precompiles/IClaimReward.sol
  • src/interfaces/precompiles/IDelegation.sol
  • src/libraries/ActionAttributes.sol
  • src/libraries/Errors.sol
  • src/storage/ClientChainGatewayStorage.sol
  • test/foundry/Delegation.t.sol
  • test/foundry/DepositWithdrawPrinciple.t.sol
  • test/foundry/ExocoreDeployer.t.sol
  • test/foundry/WithdrawReward.t.sol
  • test/foundry/unit/Bootstrap.t.sol
  • test/foundry/unit/ClientChainGateway.t.sol
  • test/foundry/unit/ExocoreGateway.t.sol
  • test/mocks/ClaimRewardMock.sol
  • test/mocks/DelegationMock.sol
  • test/mocks/PrecompileCallerMock.sol
Additional context used
Learnings (5)
src/core/ClientGatewayLzReceiver.sol (2)
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ClientGatewayLzReceiver.sol:85-93
Timestamp: 2024-09-23T09:34:52.523Z
Learning: In the `ClientGatewayLzReceiver` contract's `_handleResponse` function, the `ResponseProcessed` event includes a boolean indicating whether the request was successfully executed on Exocore, so explicit handling of failure cases within `_handleResponse` is unnecessary.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ClientGatewayLzReceiver.sol:62-64
Timestamp: 2024-09-23T09:37:05.474Z
Learning: In the `ClientGatewayLzReceiver` contract, using `address(this).call` to invoke internal functions is acceptable, as it benefits general message handling and does not increase gas consumption.
src/core/ExocoreGateway.sol (5)
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:459-466
Timestamp: 2024-09-25T02:26:07.302Z
Learning: In the `ExocoreGateway` contract, when delegate/undelegate operations fail in `handleDelegation` and `handleDepositAndDelegate`, we should consume the request, emit the event, and not revert.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:313-315
Timestamp: 2024-09-23T10:03:22.440Z
Learning: When using `address(this).call(...)`, `msg.sender` becomes `address(this)`, so functions with the `onlyCalledFromThis` modifier will function correctly.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:425-438
Timestamp: 2024-09-23T10:01:38.842Z
Learning: In the `handleDelegation` function of `ExocoreGateway.sol`, the `operator` variable is converted from a string, so casting from `bytes` to `string` is safe because `operator` will always contain valid UTF-8 encoded characters.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:305-306
Timestamp: 2024-09-23T09:39:44.021Z
Learning: Within `ExocoreGateway.sol`, the `_validateMessageLength` function ensures that `message` has sufficient length, so additional length checks after calling `_validateMessageLength` are unnecessary.
Learnt from: MaxMustermann2
PR: ExocoreNetwork/exocore-contracts#96
File: src/core/ExocoreGateway.sol:340-341
Timestamp: 2024-09-22T10:48:21.801Z
Learning: In `ExocoreGateway`, the payload length is validated in `_lzReceive`, so additional checks in functions like `handleLSTTransfer` are unnecessary.
test/foundry/DepositThenDelegateTo.t.sol (2)
Learnt from: MaxMustermann2
PR: ExocoreNetwork/exocore-contracts#96
File: test/foundry/DepositThenDelegateTo.t.sol:235-236
Timestamp: 2024-09-22T10:51:25.359Z
Learning: In Foundry tests, when using `vm.expectEmit`, you should also include the manual `emit` statement to specify the expected event parameters.
Learnt from: MaxMustermann2
PR: ExocoreNetwork/exocore-contracts#96
File: test/foundry/DepositThenDelegateTo.t.sol:163-165
Timestamp: 2024-09-22T10:51:00.426Z
Learning: In Foundry tests, after calling `vm.expectEmit()`, it's correct to specify the expected event using `emit EventName(...)`.
test/mocks/AssetsMock.sol (2)
Learnt from: bwhour
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/AssetsMock.sol:75-90
Timestamp: 2024-09-21T06:01:54.422Z
Learning: In the `withdrawNST` function of `AssetsMock.sol`, the `validatorPubkey.length` should be 32 bytes, not 48 bytes.
Learnt from: bwhour
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/AssetsMock.sol:37-49
Timestamp: 2024-09-21T06:01:19.718Z
Learning: In the `depositNST` and `withdrawNST` functions, the `validatorPubkey` has a length of 32 bytes.
test/mocks/ExocoreGatewayMock.sol (3)
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/ExocoreGatewayMock.sol:523-523
Timestamp: 2024-09-25T02:23:30.105Z
Learning: In mock contracts like `ExocoreGatewayMock`, it's acceptable to leave function parameters as `memory` without optimizing to `calldata` for gas savings.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/ExocoreGatewayMock.sol:338-366
Timestamp: 2024-09-23T09:39:05.445Z
Learning: In the `ExocoreGateway`, deposit operations are intended to be must-succeed and should revert on failure, while withdrawal failures are acceptable and should not trigger a revert.
Learnt from: adu-web3
PR: ExocoreNetwork/exocore-contracts#96
File: test/mocks/ExocoreGatewayMock.sol:144-149
Timestamp: 2024-09-23T09:40:29.126Z
Learning: When reviewing mock contracts, optimizations for error handling are not necessary.
Additional comments not posted (44)
src/storage/GatewayStorage.sol (1)

4-4: Centralized error handling introduced.

The import of the Errors library indicates a shift towards centralized error handling. This change is consistent with the removal of individual error definitions noted in the summary and should lead to more consistent error management across the codebase.

src/storage/ExocoreGatewayStorage.sol (5)

4-6: Improved code organization with new imports

The addition of these imports suggests a well-structured approach to code organization:

  • ActionAttributes library for action-related functionality
  • Errors for centralized error handling
  • Action and GatewayStorage for base storage contract integration

This refactoring enhances modularity and maintainability.


13-13: Appropriate use of ActionAttributes library

The addition of using ActionAttributes for Action; is consistent with the new imports and allows for clean usage of ActionAttributes library functions with Action type variables. This enhances code readability and maintainability.


52-52: Well-structured ClaimRewardResult event

The new ClaimRewardResult event provides comprehensive information about reward withdrawal operations. The use of indexed parameters for success, token, and withdrawer allows for efficient event filtering. This event structure is consistent with other events in the contract and enhances the contract's observability.


54-61: Efficient LSTTransfer event for deposit and withdrawal operations

The new LSTTransfer event efficiently consolidates both deposit and withdrawal operations for Liquid Staking Tokens (LST). The use of the isDeposit boolean parameter allows for a single event to handle both scenarios, reducing code duplication. The event structure, including indexed parameters, is consistent with other events in the contract and provides comprehensive information about LST transfers.


64-71: Comprehensive NSTTransfer event for Native Staking Token operations

The new NSTTransfer event effectively captures Native Staking Token (NST) transfer operations. It follows a similar structure to the LSTTransfer event, maintaining consistency in the contract. The notable inclusion of the validatorPubkey parameter is particularly relevant for NST operations, providing crucial information for tracking and auditing purposes. This event enhances the contract's ability to monitor and log NST-specific activities.

test/mocks/AssetsMock.sol (6)

10-10: LGTM: New mapping for tracking validator set membership

The addition of the inValidatorSet mapping is appropriate for tracking whether a staker is part of a validator set. This aligns with the PR objectives to separate NST and LST operations.


21-34: LGTM: Improved LST deposit handling

The changes to the depositLST function (previously depositTo) enhance its functionality and align with the PR objectives:

  1. The renaming clarifies the function's purpose.
  2. New requirements prevent NST deposits and ensure the token is registered.
  3. Input validation has been improved.

These changes effectively separate LST operations from NST operations.


37-49: LGTM: New function for NST deposits

The depositNST function is a good addition that aligns with the PR objectives:

  1. It correctly handles NST deposits using the VIRTUAL_STAKED_ETH_ADDRESS.
  2. It updates both principalBalances and inValidatorSet appropriately.
  3. The implementation separates NST operations from LST operations as intended.

Note: While there's no validation for validatorPubkey length, this is acceptable for a mock contract used in testing.


51-72: LGTM: Enhanced LST withdrawal handling

The changes to the withdrawLST function (previously withdrawPrincipal) improve its functionality and align with the PR objectives:

  1. The renaming clarifies the function's purpose.
  2. New checks prevent NST withdrawals and ensure the token is registered.
  3. The balance check is now performed before the withdrawal, which is a good practice.

These changes effectively separate LST operations from NST operations and improve the overall robustness of the function.


75-90: LGTM: New function for NST withdrawals

The withdrawNST function is a valuable addition that aligns with the PR objectives:

  1. It correctly handles NST withdrawals using the VIRTUAL_STAKED_ETH_ADDRESS.
  2. It updates both principalBalances and inValidatorSet appropriately.
  3. The implementation separates NST operations from LST operations as intended.

Note: While there's no validation for validatorPubkey length, this is acceptable for a mock contract used in testing.


Line range hint 1-91: Overall: Well-implemented changes for NST/LST separation

The changes in this mock contract effectively achieve the PR objectives of separating NST deposit/withdrawal from LST deposit/withdrawal. The new functions and modifications to existing ones provide a clear distinction between NST and LST operations, which will be beneficial for testing purposes.

Key improvements:

  1. Introduction of inValidatorSet mapping for tracking validator set membership.
  2. Clear separation of LST and NST operations in deposit and withdrawal functions.
  3. Consistent use of VIRTUAL_STAKED_ETH_ADDRESS for NST operations.

The implementation is appropriate for a mock contract used in testing, striking a balance between functionality and simplicity.

src/core/ClientGatewayLzReceiver.sol (3)

6-10: Improved code organization with new imports

The addition of new imports, particularly ActionAttributes, Action, and Errors, indicates a positive move towards better code organization and modularization. The use of an Errors library suggests a centralized approach to error handling, which can improve consistency and maintainability across the codebase.


21-21: Improved code readability with ActionAttributes

The addition of the using ActionAttributes for Action; directive is a good practice. It allows for more concise and readable code when working with Action enums by enabling the use of helper functions directly on Action variables.


180-182: Consistent error handling in afterReceiveAddWhitelistTokenRequest

The use of the Errors library for handling invalid message length in the afterReceiveAddWhitelistTokenRequest function is a good change. It improves consistency in error reporting across the contract and aligns with the overall error handling strategy.

test/foundry/DepositThenDelegateTo.t.sol (7)

6-6: Improved import statement

The import statement has been updated to include the Action enum along with GatewayStorage. This change is beneficial as it allows direct use of the Action enum in the test file, improving code readability and potentially reducing compilation time by importing only what's necessary.


25-34: Enhanced event structures for improved clarity

The new LSTTransfer and DelegationRequest events provide more detailed and flexible representations of deposit, withdrawal, and delegation operations. The inclusion of boolean flags (isDeposit and isDelegate) allows these events to cover multiple scenarios, reducing code duplication. The accepted status in DelegationRequest adds valuable information about the outcome of delegation attempts.

These changes enhance the test's ability to verify complex scenarios and improve the overall clarity of the contract's behavior.


113-113: Simplified Action enum usage

The direct use of Action.REQUEST_DEPOSIT_THEN_DELEGATE_TO instead of GatewayStorage.Action.REQUEST_DEPOSIT_THEN_DELEGATE_TO improves code readability and is consistent with the updated import statement. This change reduces verbosity without sacrificing clarity.


136-137: Consistent use of Action enum

The MessageSent event emission now uses Action.REQUEST_DEPOSIT_THEN_DELEGATE_TO directly, maintaining consistency with the earlier changes. This approach ensures uniform usage of the Action enum throughout the test file, enhancing code consistency and readability.


Line range hint 152-218: Improved test function for successful request execution

The _testRequestExecutionSuccess function (formerly _testResponse) has been significantly enhanced:

  1. The new name clearly indicates the function's purpose, improving code readability.
  2. Event expectations for LSTTransfer and DelegationRequest have been added, aligning with the new event structures and providing more comprehensive testing.
  3. The MessageExecuted event now uses the Action enum directly, maintaining consistency with earlier changes.

These improvements enhance the test's ability to verify the correct behavior of successful deposit and delegation operations.


220-288: Comprehensive testing for request execution failure scenario

The new _testRequestExecutionFailure function is a valuable addition to the test suite:

  1. It simulates a scenario where the deposit succeeds but the delegation fails, covering an important edge case.
  2. The function uses vm.mockCall to simulate the delegation failure, demonstrating good use of Foundry's mocking capabilities.
  3. It verifies the correct emission of events and state changes in the failure scenario.
  4. The use of vm.clearMockedCalls at the end ensures that the test environment is cleaned up, preventing potential interference with other tests.

This function significantly enhances the robustness of the test suite by covering failure scenarios, which is crucial for ensuring the contract behaves correctly under all conditions.


Line range hint 1-288: Overall improvement in test structure and coverage

The changes made to this test file represent a significant improvement in both structure and coverage:

  1. The new event structures (LSTTransfer and DelegationRequest) provide more detailed and flexible representations of the contract's operations.
  2. The addition of the _testRequestExecutionFailure function enhances the test suite's robustness by covering failure scenarios.
  3. Consistent use of the Action enum throughout the file improves readability and maintainability.
  4. The renaming of test functions to more descriptive names (e.g., _testRequestExecutionSuccess) enhances code clarity.

These changes collectively contribute to a more comprehensive and maintainable test suite, which is crucial for ensuring the reliability of the contract under various scenarios.

src/storage/BootstrapStorage.sol (3)

129-131: LGTM: Addition of VIRTUAL_NST_ADDRESS constant

The addition of the VIRTUAL_NST_ADDRESS constant is a good practice for handling native staking tokens alongside ERC20 tokens. The chosen address (0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE) is a widely recognized convention for representing native tokens in smart contracts.


324-324: LGTM: Improved error handling in _getVault function

The replacement of the custom error VaultNotExist with Errors.VaultDoesNotExist() indicates a shift towards a centralized error handling system. This change enhances consistency across the contract and makes error management more maintainable.


338-340: LGTM: Prevention of vault deployment for native staking token

The addition of a check to prevent vault deployment for VIRTUAL_NST_ADDRESS is a good safeguard. It ensures that no vault is created for the native staking token, which is typically handled differently from ERC20 tokens. This change is consistent with the introduction of the VIRTUAL_NST_ADDRESS constant and maintains the contract's logical integrity.

src/core/ExocoreGateway.sol (7)

80-89: Function selectors are correctly initialized

The _initializeWhitelistFunctionSelectors function correctly maps actions to their respective handler functions, ensuring proper routing of requests.


295-324: Message handling in _lzReceive is correctly implemented

The _lzReceive function appropriately validates the message length, decodes the action, calls the correct handler using the whitelist, and manages responses. Error handling is correctly implemented, ensuring that invalid requests are reverted.


335-356: handleLSTTransfer correctly processes LST transfers

The handleLSTTransfer function correctly handles deposit and withdrawal of LST tokens. It appropriately distinguishes between deposit and withdrawal actions, interacts with the ASSETS_CONTRACT, and emits the LSTTransfer event.


359-388: handleNSTTransfer correctly processes NST transfers

The handleNSTTransfer function accurately processes deposit and withdrawal of NST tokens, interacting with the ASSETS_CONTRACT and emitting the NSTTransfer event. The logic mirrors that of handleLSTTransfer, ensuring consistency.


425-438: handleDelegation handles delegation requests appropriately

The handleDelegation function correctly processes both delegation and undelegation actions. It interacts with the DELEGATION_CONTRACT and emits the DelegationRequest event with the expected parameters.


453-466: handleDepositAndDelegate correctly executes combined operations

The handleDepositAndDelegate function properly performs both deposit and delegation operations in sequence. It correctly handles the success of the deposit and proceeds to delegate, emitting appropriate events. This aligns with the intended behavior as per previous discussions.


480-492: handleOperatorAssociation operates correctly

The handleOperatorAssociation function effectively handles the associating and dissociating of operators based on the action type. It interacts with the DELEGATION_CONTRACT, handles success flags appropriately, and emits the AssociationResult event.

test/mocks/ExocoreGatewayMock.sol (12)

81-86: Validation added in initialize enhances security

The addition of a zero address check for owner_ and the use of ReentrancyGuard initialization strengthen the contract's resilience against misconfiguration and reentrancy attacks.


95-106: Function selectors initialized correctly in _initializeWhitelistFunctionSelectors

The mapping of action types to their respective handler functions ensures proper message routing and handling of various operations.


109-114: Addition of pause and unpause functions for contract control

Implementing these functions allows the contract owner to manage the contract's operational state effectively, enhancing control during maintenance or emergency situations.


242-258: Implementation of operator association in associateOperatorWithEVMStaker

The function correctly encodes the staker's address and interfaces with the DELEGATION_CONTRACT to associate an operator. Input validation and error handling are appropriately managed.


268-273: Implementation of operator dissociation in dissociateOperatorFromEVMStaker

The function properly handles the dissociation of an operator from a staker, ensuring that the staker's address is correctly encoded and error conditions are handled.


322-333: Robust message handling in _lzReceive

The function accurately extracts the action from incoming messages and dispatches them to the correct handler functions. It includes necessary validations and error handling for unsupported requests and call failures.


338-366: Correct handling of LST transfers in handleLSTTransfer

The function processes both deposit and withdrawal of Liquid Staking Tokens accurately, updating balances and emitting events as expected. The error handling aligns with the intended contract behavior for deposit operations.


369-397: Correct handling of NST transfers in handleNSTTransfer

Similar to LST handling, this function manages deposits and withdrawals of Native Staking Tokens appropriately, with consistent balance updates and event emissions.


400-418: Effective reward operation handling in handleRewardOperation

The function successfully interfaces with the CLAIM_REWARD_CONTRACT to process reward claims, ensuring that balances are updated and results are communicated back.


421-446: Proper delegation handling in handleDelegation

The function accurately differentiates between delegation and undelegation actions, invoking the correct methods and handling responses appropriately.


449-473: Efficient combined operations in handleDepositAndDelegate

By combining deposit and delegation into a single function, the contract ensures atomic execution of these related actions, maintaining consistency and efficiency.


476-498: Handling operator association requests in handleOperatorAssociation

The function properly manages both association and dissociation of operators without the need for response messages, simplifying the interchain communication flow.

src/storage/GatewayStorage.sol Show resolved Hide resolved
src/storage/ExocoreGatewayStorage.sol Show resolved Hide resolved
src/core/ExocoreGateway.sol Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
docs/native_deposit_workflow.wsd (1)

61-61: Approved: Improved error message clarity

The change from "CapsuleNotExist" to "CapsuleDoesNotExist" improves the clarity and grammatical correctness of the error message. This enhancement contributes to better code readability and maintainability.

Consider reviewing and updating similar error messages throughout the codebase to ensure consistent grammatical correctness. This will further improve the overall code quality and developer experience.

docs/client-chain-contracts-design.md (1)

14-19: Approve changes with minor suggestions for improvement

The additions of Bootstrap, ExoCapsule, and NativeRestakingController, along with the reordering of components, significantly enhance the documentation's completeness and structure. The brief descriptions for each component provide a clear overview of their roles in the system.

Consider the following minor improvements:

  1. Line 14: Change "bootstraping" to "bootstrapping".
  2. Line 19: Change "It provide functions" to "It provides functions".
  3. Consider adding a blank line between each numbered item for improved readability.
🧰 Tools
LanguageTool

[uncategorized] ~14-~14: Loose punctuation mark.
Context: ... contracts architecture: 1. Bootstrap: The contract is used for bootstraping t...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~15-~15: Loose punctuation mark.
Context: ...e Exocore chain. 2. ClientChainGateway: This is the entry point where client ch...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~16-~16: Loose punctuation mark.
Context: ...om the Exocore validator set. 3. Vault: This is where user funds are taken into...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~17-~17: Loose punctuation mark.
Context: ...one Vault. 4. LSTRestakingController: The controller is responsible for manag...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~18-~18: Loose punctuation mark.
Context: ...mented by the Gateway. 5. ExoCapsule: The contract is used as the withdrawal ...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~19-~19: Loose punctuation mark.
Context: ...contract. 6. NativeRestakingController: The controller is responsible for manag...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~19-~19: After ‘It’, use the third-person verb form “provides”.
Context: ...for managing multiple ExoCapsules. It provide functions for Ethereum native restaking...

(IT_VBZ)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 359e229 and efc1463.

🔇 Files ignored due to path filters (6)
  • docs/delegate.drawio.svg is excluded by !**/*.svg
  • docs/delegate.svg is excluded by !**/*.svg
  • docs/deposit.drawio.svg is excluded by !**/*.svg
  • docs/deposit.svg is excluded by !**/*.svg
  • docs/withdraw.drawio.svg is excluded by !**/*.svg
  • docs/withdraw.svg is excluded by !**/*.svg
📒 Files selected for processing (2)
  • docs/client-chain-contracts-design.md (2 hunks)
  • docs/native_deposit_workflow.wsd (2 hunks)
🧰 Additional context used
LanguageTool
docs/client-chain-contracts-design.md

[uncategorized] ~14-~14: Loose punctuation mark.
Context: ... contracts architecture: 1. Bootstrap: The contract is used for bootstraping t...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~15-~15: Loose punctuation mark.
Context: ...e Exocore chain. 2. ClientChainGateway: This is the entry point where client ch...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~16-~16: Loose punctuation mark.
Context: ...om the Exocore validator set. 3. Vault: This is where user funds are taken into...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~17-~17: Loose punctuation mark.
Context: ...one Vault. 4. LSTRestakingController: The controller is responsible for manag...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~18-~18: Loose punctuation mark.
Context: ...mented by the Gateway. 5. ExoCapsule: The contract is used as the withdrawal ...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~19-~19: Loose punctuation mark.
Context: ...contract. 6. NativeRestakingController: The controller is responsible for manag...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~19-~19: After ‘It’, use the third-person verb form “provides”.
Context: ...for managing multiple ExoCapsules. It provide functions for Ethereum native restaking...

(IT_VBZ)

🔇 Additional comments not posted (5)
docs/native_deposit_workflow.wsd (3)

38-39: Approved: Method names updated to reflect NST-specific operations

The changes in method names from requestDepositTo to handleNSTTransfer and depositTo to depositNST align well with the PR objective of separating Native Staking Token (NST) operations from Liquid Staking Token (LST) operations. These new method names are more specific and clearly indicate their purpose in handling NST transfers.


47-47: Approved: Optimized response handling with event emission

The change from sending a response back to ExocoreL0Endpoint to emitting an NSTTransfer event aligns with the optimization goal mentioned in Issue #3. This modification potentially reduces gas costs by eliminating unnecessary responses and simplifies the workflow. It's a good step towards optimizing the LayerZero relaying fees.


Line range hint 1-139: Summary: UML diagram updates accurately reflect PR objectives

The changes made to this UML diagram effectively represent the separation of Native Staking Token (NST) and Liquid Staking Token (LST) operations, optimize the workflow by reducing unnecessary responses, and improve error messaging. These modifications align well with the PR objectives and address concerns raised in the linked issues.

To ensure consistency across the codebase, please run the following script to check for any remaining instances of "CapsuleNotExist" that might need updating:

docs/client-chain-contracts-design.md (2)

Line range hint 1-266: Summary of documentation changes

The changes to this documentation file significantly improve its completeness and clarity. The addition of new components (Bootstrap, ExoCapsule, and NativeRestakingController) and the reordering of existing ones provide a more comprehensive overview of the system architecture. The simplification of the delegation workflow is a notable improvement that should enhance user experience.

While the changes are generally positive, there are a few areas that could benefit from minor refinements:

  1. Some grammatical improvements in the overview section.
  2. Clarification on error handling in the new delegation workflow.

Overall, these changes represent a substantial improvement to the documentation and should help developers better understand the system's architecture and workflows.

🧰 Tools
LanguageTool

[uncategorized] ~14-~14: Loose punctuation mark.
Context: ... contracts architecture: 1. Bootstrap: The contract is used for bootstraping t...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~15-~15: Loose punctuation mark.
Context: ...e Exocore chain. 2. ClientChainGateway: This is the entry point where client ch...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~16-~16: Loose punctuation mark.
Context: ...om the Exocore validator set. 3. Vault: This is where user funds are taken into...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~17-~17: Loose punctuation mark.
Context: ...one Vault. 4. LSTRestakingController: The controller is responsible for manag...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~18-~18: Loose punctuation mark.
Context: ...mented by the Gateway. 5. ExoCapsule: The contract is used as the withdrawal ...

(UNLIKELY_OPENING_PUNCTUATION)


[uncategorized] ~19-~19: Loose punctuation mark.
Context: ...contract. 6. NativeRestakingController: The controller is responsible for manag...

(UNLIKELY_OPENING_PUNCTUATION)


[grammar] ~19-~19: After ‘It’, use the third-person verb form “provides”.
Context: ...for managing multiple ExoCapsules. It provide functions for Ethereum native restaking...

(IT_VBZ)


266-266: Approve simplified delegation workflow with a request for clarification

The simplification of the delegation workflow to a single transaction improves the user experience and potentially enhances efficiency. The use of events for success/failure notification is a common and effective pattern in blockchain systems.

Could you please clarify the error handling mechanism in this new workflow? Specifically:

  1. How will users be notified of failures if there's no direct response from Exocore?
  2. Are there any plans to implement a way for the client-side application to listen for and interpret the events emitted by ExocoreGateway?

To verify the event emission, we can run the following script:

✅ Verification successful

Delegation event emissions verified successfully

The ExocoreGateway contract emits events such as DelegationRequest and AssociationResult with success indicators, effectively communicating the status of delegation operations without requiring a direct response.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the event emission in ExocoreGateway for delegation status

# Test: Search for event emission related to delegation status
ast-grep --lang solidity --pattern 'emit $_(string $_, bool $_)'

Length of output: 183


Script:

#!/bin/bash
# Description: Verify the event emission in ExocoreGateway for delegation status

# Find Solidity files related to ExocoreGateway and search for 'emit' statements
fd -e solidity | grep -i 'ExocoreGateway' | xargs rg 'emit\s+\w+\s*\('

Length of output: 17828

@adu-web3 adu-web3 added this pull request to the merge queue Sep 25, 2024
Merged via the queue into ExocoreNetwork:main with commit e6e342f Sep 25, 2024
7 checks passed
@adu-web3 adu-web3 deleted the update-balance branch September 25, 2024 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants