feat: add Moonwell lending provider (Base, Optimism)#46
Conversation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove dead code: unused callGetAccountSnapshot function and abandoned priceUSD sentinel block in fetchMarkets - Simplify price mantissa handling by storing it directly in the phase1Data struct instead of recovering via a separate loop - Add --rpc-url flag to lend positions command so Moonwell (which reads from the chain via RPC) can use custom endpoints - Fix --providers help text on yield opportunities and yield positions commands to include moonwell - Fix --provider help text on lend plan and yield plan commands to include moonwell - Add len(dec) guard in planner execMulticall3 to prevent potential panic on empty aggregate3 response Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Moonwell uses Compound v2 contracts where all calls operate on msg.sender only. Passing --on-behalf-of was silently ignored. Now returns CodeUnsupported error early, matching the existing alternate-recipient rejection in the planner. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolve conflicts: CHANGELOG.md (interleave Moonwell + analytics entries), runner.go (keep both --rpc-url flag and MarkFlagRequired calls). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Update lending, yield, quickstart, providers-and-auth, and execution-design docs to include Moonwell as a supported provider on Base and Optimism. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| rawResults := dec[0].([]struct { | ||
| Success bool `json:"success"` | ||
| ReturnData []byte `json:"returnData"` | ||
| }) |
There was a problem hiding this comment.
Unchecked type assertion can panic on malformed RPC
Medium Severity
plannerExecMulticall3 uses an unchecked type assertion (dec[0].([]struct{...})) that will panic if the RPC returns unexpected data. The equivalent function execMulticall3 in client.go uses the safe form (decoded[0].([]struct{...}) with , ok check and error return). A malformed or unexpected RPC response would crash the CLI instead of returning a user-friendly error.
Additional Locations (1)
| func MoonwellRewardDistributor(chainID int64) (string, bool) { | ||
| value, ok := moonwellRewardDistributorByChainID[chainID] | ||
| return value, ok | ||
| } |
There was a problem hiding this comment.
Exported function MoonwellRewardDistributor is never called anywhere
Low Severity
MoonwellRewardDistributor and its backing map moonwellRewardDistributorByChainID are defined and exported but never referenced anywhere in the codebase. A grep for MoonwellRewardDistributor only returns the definition site. This is dead code that adds maintenance burden without providing any value.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d33f4bc398
ℹ️ 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".
| // "max" resolves to uint256.max — used by repay to close full borrow balance. | ||
| if strings.EqualFold(strings.TrimSpace(baseUnits), "max") { | ||
| return MaxUint256, "max", nil |
There was a problem hiding this comment.
Scope
max amount sentinel to repay-only flows
NormalizeAmount now converts --amount max to uint256.max unconditionally, but this helper is shared by many non-repay paths (swap/bridge quotes and lend/yield planners). As a result, commands that do not define a max semantic now accept it and proceed with an unrealistic base-unit amount instead of returning a usage error, which can produce unusable quotes or reverting plans (for example, withdraw paths become redeemUnderlying(2^256-1)). This is a behavior regression from strict numeric validation and should be gated to the specific repay flows that support it.
Useful? React with 👍 / 👎.


Summary
lend supply|withdraw|borrow|repayandyield deposit|withdrawusing Compound v2-style mToken contracts.--pool-addressfor explicit mToken.--on-behalf-ofproperly rejected (Compound v2 operates on msg.sender only).0x0b2c...ff85); bridged USDC.e added as separate entry.--amount maxsupport added (resolves to uint256.max for full-balance repay).Supersedes fork PR #36 (all original code preserved, with review fixes merged).
Security review notes
Test plan
go test ./...passesgo vet ./...passesgo build ./...passes🤖 Generated with Claude Code
Note
High Risk
High risk because it adds new on-chain RPC reading and transaction planning/execution paths (
lend/yield) with new contract/ABI metadata; mistakes could mis-route funds or break execution on supported chains.Overview
Adds Moonwell provider support across
lendandyield, wiring it into provider routing and CLI flags/enums so Moonwell can be selected for markets/rates/positions/opportunities/positions and forplan|submit|statusexecution.Implements Moonwell on-chain reads and execution planning: a new Moonwell provider client uses RPC + Multicall3 batching to compute markets/rates/positions/yield data, and a new planner builds Compound v2
mTokentransactions (with optional auto-resolution ofmTokenviaComptroller.getAllMarkets()), explicitly rejecting unsupported semantics like--on-behalf-ofand alternate recipients.Updates shared plumbing and metadata: adds Moonwell contract addresses and ABIs to the registry, extends
lend positionsrequests with an optionalrpc_url, adds--amount maxnormalization touint256.max, fixes OptimismUSDCbootstrap mapping (and addsUSDC.e), and updates README/CHANGELOG/Mintlify docs to reflect the new provider and caveats.Written by Cursor Bugbot for commit d33f4bc. This will update automatically on new commits. Configure here.