Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ docs/
node_modules

config/
scripts/
scripts/

.claude/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
[submodule "lib/solmate"]
path = lib/solmate
url = https://github.com/transmissions11/solmate
[submodule "lib/vault-v2"]
path = lib/vault-v2
url = https://github.com/morpho-org/vault-v2
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,44 @@ One can use the logic provided in the following:
- `withdrawFromVaultAmount`
- `redeemAllFromVault`

## VaultV2 related functions in Solidity:

One can use the logic provided in the following:

1. Functions to get data:

- `totalDepositVaultV2`
- `totalSharesUserVaultV2`
- `sharePriceVaultV2`
- `adaptersListVaultV2`
- `allocationById`
- `absoluteCapById`
- `relativeCapById`
- `capsById`
- `realAssetsPerAdapter`
- `idleAssetsVaultV2`
- `feeInfoVaultV2`
- `liquidityAdapterVaultV2`
- `accrueInterestView`
- `previewDepositVaultV2`
- `previewMintVaultV2`
- `previewWithdrawVaultV2`
- `previewRedeemVaultV2`
- `effectiveCapById`
- `supplyAPYVaultV2`

2. Functions to modify state:

- `depositInVaultV2`
- `mintInVaultV2`
- `withdrawFromVaultV2`
- `redeemFromVaultV2`
- `redeemAllFromVaultV2`
- `accrueInterestVaultV2`

> [!NOTE]
> The VaultV2 snippets currently support Morpho Vault V1 adapters (MetaMorpho). Support for Morpho Market adapters is not yet implemented.

## Getting Started

- Install [Foundry](https://book.getfoundry.sh/getting-started/installation)
Expand Down
17 changes: 17 additions & 0 deletions foundry.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"lib/metamorpho": {
"rev": "16b0a90e06f3785952a48b582233b75a283d6044"
},
"lib/morpho-blue": {
"rev": "55d2d99304fb3fb930c688462ae2ccabb1d533ad"
},
"lib/openzeppelin-contracts": {
"rev": "0d5f54e69b2a2058bc98651a2e200f558c84a953"
},
"lib/solmate": {
"rev": "e0e9ff05d8aa5c7c48465511f85a6efdf5d5c30d"
},
"lib/vault-v2": {
"rev": "a14db5465fb4e066be823c2601245cc1be23923a"
}
}
2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[profile.default]
src = "src"
test = "test"
evm_version = "paris"
evm_version = "cancun"
fs_permissions = [
{ access = "read", path = "./config/"},
{ access = "read", path = "./out/"}
Expand Down
1 change: 1 addition & 0 deletions lib/vault-v2
Submodule vault-v2 added at a14db5
4 changes: 2 additions & 2 deletions src/morpho-blue/VirtualHealthFactor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ contract VirtualHealthFactorSnippets {
uint256 maxBorrow = collateral.mulDivDown(collateralPrice, ORACLE_PRICE_SCALE).wMulDown(marketParams.lltv);

if (borrowed == 0) return type(uint256).max;
healthFactor = maxBorrow.wDivDown(borrowed);
return maxBorrow.wDivDown(borrowed);
}

/// @notice Calculates the health factor of a user after a virtual repayment.
Expand All @@ -60,7 +60,7 @@ contract VirtualHealthFactorSnippets {
/// @param user The address of the user whose health factor is being calculated.
/// @param repaidAssets The amount of assets to be virtually repaid.
/// @return healthFactor The calculated health factor after the virtual repayment.
function userHypotheticalHealthFactor(
function userHealthFactorAfterVirtualRepayment(
MarketParams memory marketParams,
Id id,
address user,
Expand Down
476 changes: 476 additions & 0 deletions src/vault-v2/MorphoVaultV2Snippets.sol

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions test/morpho-blue/TestVirtualHealthFactorSnippets.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ contract TestIntegrationSnippets is BaseTest {
uint256 borrowed = morpho.expectedBorrowAssets(marketParams, BORROWER);
repaymentAmount = bound(repaymentAmount, MIN_TEST_AMOUNT, borrowed);

uint256 currentHF = snippets.userHealthFactor(marketParams, id, BORROWER);
uint256 virtualHF = snippets.userHealthFactorAfterVirtualRepayment(marketParams, id, BORROWER, repaymentAmount);
uint256 currentHf = snippets.userHealthFactor(marketParams, id, BORROWER);
uint256 virtualHf = snippets.userHealthFactorAfterVirtualRepayment(marketParams, id, BORROWER, repaymentAmount);

assertGe(virtualHF, currentHF, "Virtual HF should be greater than or equal to current HF after repayment");
assertGe(virtualHf, currentHf, "Virtual Hf should be greater than or equal to current Hf after repayment");
}

function testVirtualBorrowHealthFactor(
Expand All @@ -68,10 +68,10 @@ contract TestIntegrationSnippets is BaseTest {
_generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee);
morpho.accrueInterest(marketParams);

uint256 currentHF = snippets.userHealthFactor(marketParams, id, BORROWER);
uint256 virtualHF = snippets.userHealthFactorAfterVirtualBorrow(marketParams, id, BORROWER, borrowAmount);
uint256 currentHf = snippets.userHealthFactor(marketParams, id, BORROWER);
uint256 virtualHf = snippets.userHealthFactorAfterVirtualBorrow(marketParams, id, BORROWER, borrowAmount);

assertLe(virtualHF, currentHF, "Virtual HF should be less than or equal to current HF after borrowing");
assertLe(virtualHf, currentHf, "Virtual Hf should be less than or equal to current Hf after borrowing");
}

function testVirtualRepaymentFullRepay(
Expand All @@ -84,9 +84,9 @@ contract TestIntegrationSnippets is BaseTest {
morpho.accrueInterest(marketParams);

uint256 borrowed = morpho.expectedBorrowAssets(marketParams, BORROWER);
uint256 virtualHF = snippets.userHealthFactorAfterVirtualRepayment(marketParams, id, BORROWER, borrowed);
uint256 virtualHf = snippets.userHealthFactorAfterVirtualRepayment(marketParams, id, BORROWER, borrowed);

assertEq(virtualHF, type(uint256).max, "Virtual HF should be max when repaying full amount");
assertEq(virtualHf, type(uint256).max, "Virtual Hf should be max when repaying full amount");
}

function testVirtualBorrowZeroAmount(
Expand All @@ -98,10 +98,10 @@ contract TestIntegrationSnippets is BaseTest {
_generatePendingInterest(amountSupplied, amountBorrowed, timeElapsed, fee);
morpho.accrueInterest(marketParams);

uint256 currentHF = snippets.userHealthFactor(marketParams, id, BORROWER);
uint256 virtualHF = snippets.userHealthFactorAfterVirtualBorrow(marketParams, id, BORROWER, 0);
uint256 currentHf = snippets.userHealthFactor(marketParams, id, BORROWER);
uint256 virtualHf = snippets.userHealthFactorAfterVirtualBorrow(marketParams, id, BORROWER, 0);

assertEq(virtualHF, currentHF, "Virtual HF should equal current HF when borrowing zero");
assertEq(virtualHf, currentHf, "Virtual Hf should equal current Hf when borrowing zero");
}

function _generatePendingInterest(uint256 amountSupplied, uint256 amountBorrowed, uint256 blocks, uint256 fee)
Expand Down
Loading