From 4f9d2e3d3b1b5fc0272041271b0be84a9bbda27f Mon Sep 17 00:00:00 2001 From: Quentin Garchery Date: Thu, 27 Aug 2026 18:32:37 +0200 Subject: [PATCH 1/4] correct comment about exitAssets --- src/vault-exit/VaultExitBundlesV1.sol | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/vault-exit/VaultExitBundlesV1.sol b/src/vault-exit/VaultExitBundlesV1.sol index c519e05..ac36819 100644 --- a/src/vault-exit/VaultExitBundlesV1.sol +++ b/src/vault-exit/VaultExitBundlesV1.sol @@ -106,9 +106,11 @@ contract VaultExitBundlesV1 is IVaultExitBundlesV1, IMorphoSupplyCallback, IMorp /// @dev The allowance/permit of shares can also be used to bound the max burned shares. /// @dev The vault's idle assets are withdrawn first. /// @dev The assetsToDeallocate amount is floor((exitAssets - assetsToWithdrawFromIdle) * WAD / (WAD + penalty)). - /// @dev The in-kind portion is withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error against the users). The assets value of the sum of the shares withdrawn can be greater than exitAssets, but no greater that exitAssets+N. + /// @dev The in-kind portion is withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error against the users). The sum of the assets passed as argument to the withdraw function can be greater than exitAssets, but no greater that exitAssets+N. /// @dev Requires Morpho Blue to have at least assetsToDeallocate in loan token balance. - /// @dev Requires the sender to have enough shares to withdraw exitAssets+N. + /// @dev Requires the sender to have enough shares to: + /// - first withdraw assetsToWithdrawFromIdle + /// - then withdraw ceil(assets * penalty / WAD) and withdraw assets, for each market in the list, where the sum of the assets is equal to assetsToDeallocate. /// @dev It may be the case that the vault became liquid, but calling this function still yields positions on the markets, and potentially pays the penalty. /// @dev If the liquidity adapter has some liquidity, withdrawing from the vault instead of calling this function avoids the penalty. /// @dev It's acknowledged that it is possible to call this function with duplicate markets in the list. @@ -175,7 +177,7 @@ contract VaultExitBundlesV1 is IVaultExitBundlesV1, IMorphoSupplyCallback, IMorp /// @dev Starts by withdrawing everything the vault can pay without penalty: its idle assets and the liquidity available through the liquidity adapter. /// @dev The assetsToDeallocate amount is floor((exitAssets - assetsToWithdraw) * WAD / (WAD + penalty)), where assetsToWithdraw is the amount withdrawn without penalty. /// @dev The assetsToDeallocate amount is force deallocated by looping over the adapter's markets, taking from each market as much as its liquidity and the adapter's position allow before moving to the next one. - /// @dev The assets are withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error for the users). The assets value of the sum of the shares redeemed can be greater than exitAssets, but no greater that exitAssets+N. + /// @dev The assets are withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error for the users). The sum of the assets passed as argument to the withdraw function can be greater than exitAssets, but no greater that exitAssets+N for each iteration. /// @dev The referral fee is deducted from the withdrawn assets; the remainder is sent to msg.sender. /// @dev Fee = withdrawnAssets * referralFeePct / WAD; net = withdrawnAssets - fee. /// @dev minSharePriceE27 lower-bounds the realized exit share price (withdrawn assets per share, scaled by 1e27). The force deallocate penalty is deducted from the withdrawn assets, so it lowers this price. From c51ca9ee956ca3bc461021351a6ab2300ad30aa2 Mon Sep 17 00:00:00 2001 From: Quentin Garchery Date: Fri, 28 Aug 2026 12:12:20 +0200 Subject: [PATCH 2/4] Apply suggestion from @QGarchery Signed-off-by: Quentin Garchery --- src/vault-exit/VaultExitBundlesV1.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vault-exit/VaultExitBundlesV1.sol b/src/vault-exit/VaultExitBundlesV1.sol index ac36819..ac519ee 100644 --- a/src/vault-exit/VaultExitBundlesV1.sol +++ b/src/vault-exit/VaultExitBundlesV1.sol @@ -177,7 +177,7 @@ contract VaultExitBundlesV1 is IVaultExitBundlesV1, IMorphoSupplyCallback, IMorp /// @dev Starts by withdrawing everything the vault can pay without penalty: its idle assets and the liquidity available through the liquidity adapter. /// @dev The assetsToDeallocate amount is floor((exitAssets - assetsToWithdraw) * WAD / (WAD + penalty)), where assetsToWithdraw is the amount withdrawn without penalty. /// @dev The assetsToDeallocate amount is force deallocated by looping over the adapter's markets, taking from each market as much as its liquidity and the adapter's position allow before moving to the next one. - /// @dev The assets are withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error for the users). The sum of the assets passed as argument to the withdraw function can be greater than exitAssets, but no greater that exitAssets+N for each iteration. + /// @dev The assets are withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error for the users). The sum of the assets passed as argument to the withdraw function can be greater than exitAssets, but no greater that exitAssets+N. /// @dev The referral fee is deducted from the withdrawn assets; the remainder is sent to msg.sender. /// @dev Fee = withdrawnAssets * referralFeePct / WAD; net = withdrawnAssets - fee. /// @dev minSharePriceE27 lower-bounds the realized exit share price (withdrawn assets per share, scaled by 1e27). The force deallocate penalty is deducted from the withdrawn assets, so it lowers this price. From 39de16be32be95d4c20bc2bfa47ee9218543cfe7 Mon Sep 17 00:00:00 2001 From: Quentin Garchery Date: Fri, 28 Aug 2026 16:59:02 +0200 Subject: [PATCH 3/4] Update src/vault-exit/VaultExitBundlesV1.sol Co-authored-by: Bhargav Bhatt <40268131+bhargavbh@users.noreply.github.com> Signed-off-by: Quentin Garchery --- src/vault-exit/VaultExitBundlesV1.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vault-exit/VaultExitBundlesV1.sol b/src/vault-exit/VaultExitBundlesV1.sol index ac519ee..5b78315 100644 --- a/src/vault-exit/VaultExitBundlesV1.sol +++ b/src/vault-exit/VaultExitBundlesV1.sol @@ -106,7 +106,7 @@ contract VaultExitBundlesV1 is IVaultExitBundlesV1, IMorphoSupplyCallback, IMorp /// @dev The allowance/permit of shares can also be used to bound the max burned shares. /// @dev The vault's idle assets are withdrawn first. /// @dev The assetsToDeallocate amount is floor((exitAssets - assetsToWithdrawFromIdle) * WAD / (WAD + penalty)). - /// @dev The in-kind portion is withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error against the users). The sum of the assets passed as argument to the withdraw function can be greater than exitAssets, but no greater that exitAssets+N. + /// @dev The in-kind portion is withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error against the users). The sum of the assets passed as argument to the withdraw function can be greater than exitAssets, but no greater than exitAssets+N. /// @dev Requires Morpho Blue to have at least assetsToDeallocate in loan token balance. /// @dev Requires the sender to have enough shares to: /// - first withdraw assetsToWithdrawFromIdle From dc6b02c0e6ae69018978c1ca18a9845d471e9289 Mon Sep 17 00:00:00 2001 From: Quentin Garchery Date: Fri, 28 Aug 2026 16:59:28 +0200 Subject: [PATCH 4/4] Update src/vault-exit/VaultExitBundlesV1.sol Co-authored-by: Bhargav Bhatt <40268131+bhargavbh@users.noreply.github.com> Signed-off-by: Quentin Garchery --- src/vault-exit/VaultExitBundlesV1.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vault-exit/VaultExitBundlesV1.sol b/src/vault-exit/VaultExitBundlesV1.sol index 5b78315..a2b9508 100644 --- a/src/vault-exit/VaultExitBundlesV1.sol +++ b/src/vault-exit/VaultExitBundlesV1.sol @@ -177,7 +177,7 @@ contract VaultExitBundlesV1 is IVaultExitBundlesV1, IMorphoSupplyCallback, IMorp /// @dev Starts by withdrawing everything the vault can pay without penalty: its idle assets and the liquidity available through the liquidity adapter. /// @dev The assetsToDeallocate amount is floor((exitAssets - assetsToWithdraw) * WAD / (WAD + penalty)), where assetsToWithdraw is the amount withdrawn without penalty. /// @dev The assetsToDeallocate amount is force deallocated by looping over the adapter's markets, taking from each market as much as its liquidity and the adapter's position allow before moving to the next one. - /// @dev The assets are withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error for the users). The sum of the assets passed as argument to the withdraw function can be greater than exitAssets, but no greater that exitAssets+N. + /// @dev The assets are withdrawn in a number of iterations that is bounded by N the number of markets in the adapter (each of them can result in a rounding error for the users). The sum of the assets passed as argument to the withdraw function can be greater than exitAssets, but no greater than exitAssets+N. /// @dev The referral fee is deducted from the withdrawn assets; the remainder is sent to msg.sender. /// @dev Fee = withdrawnAssets * referralFeePct / WAD; net = withdrawnAssets - fee. /// @dev minSharePriceE27 lower-bounds the realized exit share price (withdrawn assets per share, scaled by 1e27). The force deallocate penalty is deducted from the withdrawn assets, so it lowers this price.