Skip to content

feat(morpho-sdk): add native wrapping to blueRepay#827

Closed
Foulks-Plb wants to merge 6 commits into
mainfrom
amarillo-v1
Closed

feat(morpho-sdk): add native wrapping to blueRepay#827
Foulks-Plb wants to merge 6 commits into
mainfrom
amarillo-v1

Conversation

@Foulks-Plb

Copy link
Copy Markdown
Contributor

Motivation

Repaying a wNative-denominated Blue debt previously required the integrator to wrap native ETH into wNative in a separate step, even though blueSupply and blueSupplyCollateral already support native wrapping inline. This closes that gap so a repay can be funded directly with native ETH.

Solution

blueRepay now accepts an optional args.nativeAmount that funds part or all of transferAmount by prepending nativeTransfer → wrapNative (via GeneralAdapter1), with any remainder pulled through the existing ERC-20/permit path — exactly the pattern used by the supply actions. The loan token must be the chain's wNative, and in shares mode the skimmed residual is returned as wNative (documented). Adds the public BlueRepayAction.args.nativeAmount field and the exported NativeAmountExceedsTransferAmountError, plus six unit tests and a minor changeset. The entity layer (MorphoBlue.repay()) is intentionally untouched and left for a follow-up.

Allow funding part or all of a Blue repay's transferAmount by wrapping
native into wNative via GeneralAdapter1, mirroring blueSupply /
blueSupplyCollateral. Adds the optional nativeAmount arg, the
BlueRepayAction.nativeAmount field, and the exported
NativeAmountExceedsTransferAmountError.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Foulks-Plb Foulks-Plb added the enhancement New feature or request label Jun 29, 2026
@Foulks-Plb Foulks-Plb self-assigned this Jun 29, 2026
@Foulks-Plb

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

* is provided and the signed amount differs from `args.transferAmount`.

P2 Badge Use ERC-20 remainder for permit signatures

For mixed native repayments (nativeAmount > 0 with an ERC-20 remainder), blueRepay passes erc20Funding = transferAmount - nativeFunding to getRequirementsAction, so a permit/Permit2 signed for the full args.transferAmount is rejected with DepositAmountMismatchError. This public @throws text tells integrators to sign transferAmount, which makes the new mixed native+permit path fail during transaction construction; it should reference the ERC-20 remainder instead.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/morpho-sdk/src/actions/blue/repay.test.ts
- Fix DepositAmountMismatchError JSDoc to reference the ERC-20 remainder
  (transferAmount - nativeAmount) pulled in mixed native repays, not the
  full transferAmount (Codex P2).
- Reuse the WstethWethBlue fixture in blueRepay native unit tests instead
  of spreading WethUsdsBlue, whose cached MarketParams.id no longer matched
  the WETH loan-token tuple (Codex P3).
- Add fork e2e tests: full-native repay and mixed native+ERC-20 repay,
  asserting the funding split (GA1 pulls only the ERC-20 remainder).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Foulks-Plb

Copy link
Copy Markdown
Contributor Author

@codex review

@Foulks-Plb

Copy link
Copy Markdown
Contributor Author

@prd-carapulse[bot] Eeview this PR with a strong focus on security and fund safety.

Verify that no loss of funds is possible through the Bundler or the General Adapter.

Also ensure that the PR follows the Morpho SDK standards, maintains a high level of developer experience (DevEx), and is consistent with the existing architecture and conventions.

@prd-carapulse

prd-carapulse Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Verdict: ✅ No blocking issues found on current head a70efb8ca56625ddc3dfe1006b45983f1eb687e1.

Fund safety: nativeAmount path is fail-safe: negative, nativeAmount > transferAmount, no configured wNative, and non-wNative loan-token cases reject before encoding.

Bundler / GeneralAdapter flow: native funds enter as tx.value, then execute nativeTransfer(bundler3, generalAdapter1, nativeAmount, false)wrapNative(nativeAmount, generalAdapter1, false)morphoRepay. Funding/wrap/repay all use skipRevert=false, so no partial native loss can commit independently.

Mixed funding: ERC-20 pull / permit amount is exactly transferAmount - nativeAmount, so partial-native repay does not overpull WETH.

Shares mode: residual overfund remains wNative and is skimmed back to receiver; no Bundler/GA1 dust path found.

SDK standards / DevEx: action-layer scope matches PR body. Entity-layer MorphoBlue.repay() native support is explicitly left for follow-up. Types, docs, changeset, and tests are consistent with existing native supply patterns.

Verification run:

  • pnpm exec vitest --project morpho-sdk --run packages/morpho-sdk/src/actions/blue/repay.test.ts ✅ 22 passed
  • pnpm exec vitest --project morpho-sdk --run packages/morpho-sdk/test/actions/blue/repay.test.ts ✅ 10 passed
  • Review-only fork test for native by-shares full repay/residual skim ✅ passed
  • git diff --check origin/main...HEAD
  • pnpm exec biome check ...
  • pnpm --filter @morpho-org/morpho-sdk build
  • GitHub checks green: lint / biome, build / Build, test / vitest

Non-blocking suggestion: promote the by-shares native fork test into the committed suite, since that path carries the residual-skim fund-safety invariant.

Track: https://carapulse.morpho.dev/dashboard/runs?run_id=gw_run_5a81658649ed

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: b3ed36f8b1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Foulks-Plb and others added 3 commits June 29, 2026 15:48
…tests

The fully-native repay test only checked that getRequirementsAction was not
called, which proves nothing about the plain erc20TransferFrom path. Assert
on the GeneralAdapter1 call selectors instead: the fully-native bundle must
contain wrapNative and must NOT contain erc20TransferFrom, while the mixed
bundle must contain both.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Express blueRepay funding as amount (ERC-20) + nativeAmount (wrapped),
summing to the GeneralAdapter1 transfer — the same DepositAmountArgs
surface as blueSupply / blueSupplyCollateral. Mode is selected by `shares`
(omit for assets mode, set for full repay). Removes the redundant
assets/transferAmount pair from the action args; transferAmount is now
derived. Drops the now-unreachable NativeAmountExceedsTransferAmountError.

The MorphoBlue.repay() entity API and the BlueRepayAction result shape are
unchanged. Updates entity wiring, unit + e2e tests, docs, and bumps the
changeset to major with a migration guide.

BREAKING CHANGE: blueRepay args replace { assets, transferAmount } with
{ amount, nativeAmount? } that sum to the transfer; mode is set by `shares`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The repay entity now accepts an optional nativeAmount alongside
{ assets } | { shares }, giving the surface DevEx: asset, asset+native,
share, or share+native (assets/shares stay mutually exclusive). It sources
up to nativeAmount of the funding by wrapping native ETH (capped at the
required transfer, so over-providing funds the repay fully with native),
pulls the remainder as ERC-20, and getRequirements returns an approval only
for that ERC-20 remainder (empty when fully native).

Converts the native repay fork e2e tests to drive the entity API and adds a
shares-mode fully-native case. Updates docs and the changeset.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Foulks-Plb Foulks-Plb closed this Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant