Skip to content

fix: slippage revert#495

Merged
antoncoding merged 4 commits intomasterfrom
fix/slippage-leverage
Apr 10, 2026
Merged

fix: slippage revert#495
antoncoding merged 4 commits intomasterfrom
fix/slippage-leverage

Conversation

@antoncoding
Copy link
Copy Markdown
Owner

@antoncoding antoncoding commented Apr 10, 2026

Summary by CodeRabbit

  • New Features

    • Slippage control now available for ERC4626 vault collateral routes.
  • Improvements

    • Collateral preview now indicates minimum amounts for vault assets.
    • ERC4626 quote and unwind logic refined to apply slippage floors and improve loading/error handling for more accurate leverage/deleverage quotes.
    • Slippage UI visibility adjusted across the add-collateral flow.
    • Token amount formatting and USD display improved; interest tooltips show exact amounts.
    • Borrow risk card defaults to compact display and shows full-value tooltips.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
monarch Ready Ready Preview, Comment Apr 10, 2026 8:59am

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 10, 2026

📝 Walkthrough

Walkthrough

Switches ERC4626 flash-leg callback from mint→deposit, threads ERC4626 previewDeposit/previewRedeem results through leverage/deleverage quote logic with slippage-floor application, updates related UI labels/controls, replaces token-formatting calls with a new token-aware formatter, and refactors metric/tooltip rendering in several modal and table components.

Changes

Cohort / File(s) Summary
ERC4626 Leverage Hook
src/hooks/leverage/leverageWithErc4626Deposit.ts
Flash-leg callback now encodes/calls erc4626Deposit(...) instead of erc4626Mint(...); callback arg order/docs updated to treat collateral inputs as minimum share floors.
Leverage Quote Logic
src/hooks/useLeverageQuote.ts
Uses ERC4626 previewDeposit/renamed preview outputs and applies withSlippageFloor(...) to both initial-collateral and flash-leg share computations for ERC4626/loan-input paths; returns updated preview/loading/error flags.
Deleverage ERC4626 Unwind
src/hooks/deleverage/deleverageWithErc4626Redeem.ts, src/hooks/useDeleverageQuote.ts
deleverageWithErc4626Redeem now conditionally encodes erc4626Withdraw vs erc4626Redeem based on close-route flag; useDeleverageQuote replaces multi-call preview reads with a single previewRedeem read and applies slippage-floor to redeem-derived share amounts.
Leverage UI / Slippage
src/modals/leverage/components/add-collateral-and-leverage.tsx
Label updates to show "Total Collateral Added (Min.)" for ERC4626; slippage control shown for swap and ERC4626 routes; slippage editor rendering refactored.
Token formatting util
src/utils/balance.ts
Added exported formatReadableTokenAmount(value, options?) and FormatReadableTokenAmountOptions to handle precision, compacting, and "< x" min-display behavior.
Tables / Interest display
src/features/positions/components/borrowed-morpho-blue-table.tsx, src/features/positions/components/supplied-morpho-blue-grouped-table.tsx
Switched to formatReadableTokenAmount for token amounts; enhanced "Interest Accrued" tooltip to include exact token amount and USD computation via computeAssetUsdValue/formatUsdValueDisplay.
Borrow modal / metrics
src/modals/borrow/components/borrow-position-risk-card.tsx
Added TokenMetricValue helper, changed default useCompactAmountDisplay to true, and replaced inline preview/tooltip rendering with the helper component.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as Leverage UI
    participant QuoteHook as useLeverageQuote
    participant LeverageHook as leverageWithErc4626Deposit
    participant FlashLoan as FlashLoanProvider
    participant Vault as ERC4626 Vault

    User->>UI: open modal / request quote (route=erc4626)
    UI->>QuoteHook: request quote (loan input)
    QuoteHook->>Vault: previewDeposit(flashLoanAssetAmount) / previewMint (user path)
    Vault-->>QuoteHook: preview results (shares)
    QuoteHook-->>UI: quote with slippage floors (initial & flash-leg min shares)
    UI->>LeverageHook: submit leverage tx (includes min share floors)
    LeverageHook->>FlashLoan: request flash loan (assetAmount)
    FlashLoan->>LeverageHook: provide assets & invoke callback
    LeverageHook->>Vault: erc4626Deposit(assetAmount, minShares)
    Vault-->>LeverageHook: deposit result (shares minted)
    LeverageHook->>FlashLoan: repay flash loan
    LeverageHook-->>UI: tx result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'fix: slippage revert' is vague and doesn't clearly describe what the changeset addresses. Use a more specific title that describes the actual fix, such as 'fix: apply slippage floor to ERC4626 leverage and deleverage routes' or similar.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/slippage-leverage

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the bug Something isn't working label Apr 10, 2026
Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (2)
src/modals/borrow/components/borrow-position-risk-card.tsx (1)

318-350: Optional: extract a shared asset metric row.

Collateral and debt blocks now follow the same structure; a tiny helper/component could reduce duplication and future drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/modals/borrow/components/borrow-position-risk-card.tsx` around lines 318
- 350, Extract a reusable AssetMetricRow component to remove duplication between
the collateral and debt blocks: create a new component (e.g., AssetMetricRow)
that accepts props used in both instances — title, isPreview, detail,
secondaryDetail, displayAmount, fullAmount, symbol, valueClassName,
tokenAddress, chainId, tokenSymbol, and labelClassName — and replaces the
duplicated JSX where TokenIcon and TokenMetricValue are rendered; update the
collateral block to call <AssetMetricRow ...> with collateral* props
(showProjectedCollateral, collateralCurrentDetail, collateralProjectedDetail,
collateralDeltaLabel, collateralDisplay, market.collateralAsset.address,
market.morphoBlue.chain.id, metricLabelClassName, etc.) and the debt block to
call it with borrow* props (showProjectedBorrow, borrowCurrentDetail,
borrowProjectedDetail, borrowDeltaLabel, borrowDisplay,
market.loanAsset.address, market.morphoBlue.chain.id, metricLabelClassName,
etc.), preserving class names and prop names used by TokenMetricValue and
TokenIcon so behavior and styling remain unchanged.
src/features/positions/components/supplied-morpho-blue-grouped-table.tsx (1)

280-282: Optional: compute earningsPreview once per row.

formatTokenAmountPreview(...) is called twice in the same render path. Hoisting it once near const earnings = ... would simplify this block.

Also applies to: 303-306

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/features/positions/components/supplied-morpho-blue-grouped-table.tsx`
around lines 280 - 282, Hoist the call to formatTokenAmountPreview by computing
const earningsPreview = formatTokenAmountPreview(earnings,
groupedPosition.loanAssetDecimals) once per row (near where const earnings is
defined) and reuse earningsPreview.full and earningsPreview.short instead of
calling formatTokenAmountPreview again; update the places that build
exactTokenAmount and the shortened display (the duplicated calls around
exactTokenAmount and the later display at lines ~303-306) to reference the
single earningsPreview variable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/utils/balance.ts`:
- Around line 60-61: The current code uses Number.parseFloat which silently
accepts partial numeric strings; replace the parseFloat logic in the
numericValue assignment inside src/utils/balance.ts so string inputs are
strictly converted with Number (e.g. const numericValue = typeof value ===
'string' ? Number(value.trim()) : value) or validated with a strict numeric
regex before parsing, then keep the existing Number.isFinite(numericValue)
fallback; update the handling around numericValue (the same variable and
conditional) so values like "1,234.56" or "12abc" produce the fallback string
instead of a truncated number.

---

Nitpick comments:
In `@src/features/positions/components/supplied-morpho-blue-grouped-table.tsx`:
- Around line 280-282: Hoist the call to formatTokenAmountPreview by computing
const earningsPreview = formatTokenAmountPreview(earnings,
groupedPosition.loanAssetDecimals) once per row (near where const earnings is
defined) and reuse earningsPreview.full and earningsPreview.short instead of
calling formatTokenAmountPreview again; update the places that build
exactTokenAmount and the shortened display (the duplicated calls around
exactTokenAmount and the later display at lines ~303-306) to reference the
single earningsPreview variable.

In `@src/modals/borrow/components/borrow-position-risk-card.tsx`:
- Around line 318-350: Extract a reusable AssetMetricRow component to remove
duplication between the collateral and debt blocks: create a new component
(e.g., AssetMetricRow) that accepts props used in both instances — title,
isPreview, detail, secondaryDetail, displayAmount, fullAmount, symbol,
valueClassName, tokenAddress, chainId, tokenSymbol, and labelClassName — and
replaces the duplicated JSX where TokenIcon and TokenMetricValue are rendered;
update the collateral block to call <AssetMetricRow ...> with collateral* props
(showProjectedCollateral, collateralCurrentDetail, collateralProjectedDetail,
collateralDeltaLabel, collateralDisplay, market.collateralAsset.address,
market.morphoBlue.chain.id, metricLabelClassName, etc.) and the debt block to
call it with borrow* props (showProjectedBorrow, borrowCurrentDetail,
borrowProjectedDetail, borrowDeltaLabel, borrowDisplay,
market.loanAsset.address, market.morphoBlue.chain.id, metricLabelClassName,
etc.), preserving class names and prop names used by TokenMetricValue and
TokenIcon so behavior and styling remain unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: c2c006f3-64d9-437e-b01f-80099063ddff

📥 Commits

Reviewing files that changed from the base of the PR and between 39c3289 and 2a81203.

📒 Files selected for processing (4)
  • src/features/positions/components/borrowed-morpho-blue-table.tsx
  • src/features/positions/components/supplied-morpho-blue-grouped-table.tsx
  • src/modals/borrow/components/borrow-position-risk-card.tsx
  • src/utils/balance.ts

Comment thread src/utils/balance.ts
Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
src/hooks/useLeverageQuote.ts (1)

107-126: Preview uses previewMint but execution uses erc4626Deposit.

The guideline states "previewMint→exact-share mint", but the execution path uses erc4626Deposit with the previewed assets. Per the context in leverageWithErc4626Deposit.ts, this is intentional: depositing exact assets with a share floor "keeps the flash leg executable even if the vault's share price moved enough that an exact-share mint would require more assets than the flash loan supplied."

The slippage floor at line 243 protects against unfavorable price movements. The trade-off is potentially receiving slightly fewer shares than targeted if the share price increases.

Consider adding a brief comment near previewMint usage (around line 119-120) noting that execution intentionally uses deposit-with-floor rather than exact-share mint to handle share price movement.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/hooks/useLeverageQuote.ts` around lines 107 - 126, Add a short inline
comment next to the previewMint call in useLeverageQuote.ts (the useReadContract
call with functionName 'previewMint' and arg targetFlashCollateralTokenAmount)
stating that although previewMint is used to estimate exact-share requirements,
the actual execution path uses erc4626Deposit (see
leverageWithErc4626Deposit.ts) which deposits assets with a share-floor to
remain executable if the vault share price rises; mention that the
slippage/floor protection is applied at execution to avoid failing the flash
leg.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/hooks/useLeverageQuote.ts`:
- Around line 107-126: Add a short inline comment next to the previewMint call
in useLeverageQuote.ts (the useReadContract call with functionName 'previewMint'
and arg targetFlashCollateralTokenAmount) stating that although previewMint is
used to estimate exact-share requirements, the actual execution path uses
erc4626Deposit (see leverageWithErc4626Deposit.ts) which deposits assets with a
share-floor to remain executable if the vault share price rises; mention that
the slippage/floor protection is applied at execution to avoid failing the flash
leg.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: e6e48472-342d-467f-b66c-7c2fb7adad48

📥 Commits

Reviewing files that changed from the base of the PR and between 2a81203 and d4ee300.

📒 Files selected for processing (3)
  • src/hooks/deleverage/deleverageWithErc4626Redeem.ts
  • src/hooks/useDeleverageQuote.ts
  • src/hooks/useLeverageQuote.ts

@antoncoding antoncoding merged commit 34b30bd into master Apr 10, 2026
4 checks passed
@antoncoding antoncoding deleted the fix/slippage-leverage branch April 10, 2026 09:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant