Skip to content

feat: add MorphoVaultV1PositionManager library#437

Merged
keyleu merged 1 commit into
timewave-computer:mainfrom
orbitearn:main
Sep 22, 2025
Merged

feat: add MorphoVaultV1PositionManager library#437
keyleu merged 1 commit into
timewave-computer:mainfrom
orbitearn:main

Conversation

@MMujtabaRoohani-BlockApex

Copy link
Copy Markdown
Contributor

No description provided.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Summary of Changes

Hello @MMujtabaRoohani-BlockApex, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new MorphoVaultV1PositionManager Solidity library, designed to facilitate seamless and automated interaction with the Morpho Vault V1.1 protocol. It enables users to deposit and withdraw assets from Morpho vaults through a BaseAccount, ensuring efficient and secure position management. The changes also include the necessary Morpho-specific interfaces and a comprehensive test suite to validate the library's functionality and configuration handling.

Highlights

  • New Library: MorphoVaultV1PositionManager: Introduced a new Solidity library to manage positions within the Morpho Vault V1.1 protocol, enabling automated deposit and withdrawal operations.
  • Integration with BaseAccount: The new position manager leverages the existing BaseAccount contract to initiate and execute transactions, ensuring consistent account interaction.
  • Configuration Management and Validation: The library includes a robust configuration mechanism with validation checks for critical parameters such as vault address, input/output accounts, and asset addresses, enhancing security and preventing misconfigurations.
  • New Morpho Interfaces: Added IMetaMorphoV1_1.sol and IMorpho.sol interfaces to provide the necessary contract definitions for interacting with the Morpho Vault V1.1 and core Morpho protocol.
  • Comprehensive Test Coverage: A dedicated test suite, MorphoVaultV1PositionManager.t.sol, has been added to thoroughly test the new library's functionalities, including configuration updates, balance retrieval, deposit, and withdrawal processes, along with various revert conditions.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a MorphoVaultV1PositionManager library to interact with Morpho Vault V1.1, along with necessary interfaces and comprehensive tests. The implementation is solid, but there are several areas for improvement regarding security, efficiency, and code clarity. Key points include addressing a potential vulnerability in the ERC20 approval mechanism, optimizing a view function for gas savings, improving code maintainability by using custom errors and correcting some minor copy-paste errors in comments and tests. There is also a potential license compatibility issue that should be reviewed.

Comment on lines +58 to +61
//Approve the MorphoVaultV1 to spend the base asset from the input account
bytes memory encodedApproveCall = abi.encodeCall(IERC20.approve, (storedConfig.vaultAddress, depositAmount));

storedConfig.inputAccount.execute(address(asset), 0, encodedApproveCall);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The use of IERC20.approve can be unsafe for certain tokens (like USDT) that don't revert when changing a non-zero allowance. This can lead to a race condition. It's highly recommended to use a safe approval mechanism. Since you are encoding the call, you can't directly use OpenZeppelin's SafeERC20 library.

A common pattern to mitigate this is to first approve zero, and then the desired amount. However, this would require two separate execute calls, increasing gas costs.

Consider if the BaseAccount can be extended with a safeApprove function or a multicall capability. A simpler, though less flexible, approach would be to approve type(uint256).max once during configuration and remove the repeated approve calls from the deposit function.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the inputAccount is meant to be interacting with only this library hence we don't expect a non-zero approval before or after this function call.

@@ -0,0 +1,268 @@
// SPDX-License-Identifier: GPL-2.0-or-later

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The SPDX license identifier is GPL-2.0-or-later, while other new files in this PR like MorphoVaultV1PositionManager.sol use Apache-2.0. Using code with a GPL license can have implications for the licensing of the entire project, as GPL is a 'copyleft' license. Please ensure this is intentional and compliant with your project's licensing policy. This also applies to solidity/src/libraries/interfaces/morpho/IMorpho.sol.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is intentional, the interfaces are taken from Morpho and carries the license from there.

Comment thread solidity/src/libraries/MorphoVaultV1PositionManager.sol Outdated
Comment thread solidity/src/libraries/MorphoVaultV1PositionManager.sol Outdated
Comment on lines +123 to +125
if (decodedConfig.vaultAddress == address(0)) {
revert("Vault address can't be zero address");
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

For gas efficiency and better error handling, it's recommended to use custom errors instead of revert strings. This applies to all require and revert statements in the contract.

For example:

error VaultAddressIsZero();

// ...

if (decodedConfig.vaultAddress == address(0)) {
    revert VaultAddressIsZero();
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We follow the string practice as it is easy to debug and these functions are meant to be used in rare conditions.

Comment on lines +145 to +149
function balance() public view returns (uint256) {
return IMetaMorphoV1_1(config.vaultAddress).previewRedeem(
IMetaMorphoV1_1(config.vaultAddress).balanceOf(address(config.inputAccount))
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The balance function can be optimized for gas efficiency. The current implementation results in multiple SLOAD operations. Caching the config struct in memory will reduce gas costs by performing a single SLOAD for the struct and then reading from memory.

    function balance() public view returns (uint256) {
        MorphoVaultV1PositionManagerConfig memory storedConfig = config;
        IMetaMorphoV1_1 vault = IMetaMorphoV1_1(storedConfig.vaultAddress);
        return vault.previewRedeem(vault.balanceOf(address(storedConfig.inputAccount)));
    }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Perfect, made the balance function external view function so we don't have to worry about gas.

Comment thread solidity/test/libraries/MorphoVaultV1PositionManager.t.sol Outdated
Comment thread solidity/test/libraries/MorphoVaultV1PositionManager.t.sol Outdated
Comment thread solidity/test/libraries/MorphoVaultV1PositionManager.t.sol Outdated
Comment thread solidity/test/libraries/MorphoVaultV1PositionManager.t.sol Outdated
Co-authored-by: HareemSaad <hareems20014@outlook.com>

@keyleu keyleu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

@keyleu keyleu merged commit ace5625 into timewave-computer:main Sep 22, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants