diff --git a/.changeset/vaultv1-deposit-forward-accrual.md b/.changeset/vaultv1-deposit-forward-accrual.md new file mode 100644 index 000000000..8ebe76920 --- /dev/null +++ b/.changeset/vaultv1-deposit-forward-accrual.md @@ -0,0 +1,5 @@ +--- +"@morpho-org/morpho-sdk": patch +--- + +Fix `MorphoVaultV1.deposit` deriving `maxSharePrice` from pre-accrue vault state. MetaMorpho's `deposit` calls `_accrueInterest()`, so the execution-time share price is `>=` the build-time one; without a forward-accrual buffer the slippage bound could be too tight and revert GeneralAdapter1's check with `SlippageExceeded`. VaultV1 deposit now forward-accrues interest by 2h before computing shares, mirroring `MorphoVaultV2.deposit` and blue repay. diff --git a/packages/morpho-sdk/src/entities/vaultV1/vaultV1.ts b/packages/morpho-sdk/src/entities/vaultV1/vaultV1.ts index 5f9f0def7..2abb6ec40 100644 --- a/packages/morpho-sdk/src/entities/vaultV1/vaultV1.ts +++ b/packages/morpho-sdk/src/entities/vaultV1/vaultV1.ts @@ -223,7 +223,20 @@ export class MorphoVaultV1 implements VaultV1Actions { const totalAssets = amount + (nativeAmount ?? 0n); - const shares = vaultData.toShares(totalAssets); + // Forward-accrue 2h so maxSharePrice bounds the execution-time price, like + // VaultV2 deposit and blue repay. MetaMorpho has no vault-level lastUpdate, + // so accrue to the latest of now and every allocated market's lastUpdate + // (accrueInterest throws below any market's lastUpdate). + const accrualTimestamp = + vaultData.allocations + .values() + .reduce( + (max, { position }) => MathLib.max(max, position.market.lastUpdate), + Time.timestamp(), + ) + Time.s.from.h(2n); + const accruedVault = vaultData.accrueInterest(accrualTimestamp); + + const shares = accruedVault.toShares(totalAssets); if (shares <= 0n) { throw new NonPositiveSharesAmountError(this.vault); }