Skip to content

feat(defi): add DeFi meta-protocols (lp, lend, perps, bet)#423

Open
jpthor wants to merge 2 commits intomainfrom
jp/defi
Open

feat(defi): add DeFi meta-protocols (lp, lend, perps, bet)#423
jpthor wants to merge 2 commits intomainfrom
jp/defi

Conversation

@jpthor
Copy link
Collaborator

@jpthor jpthor commented Jan 6, 2026

Summary

Adds comprehensive DeFi meta-protocol support to the recipes engine, enabling high-level abstractions for common DeFi operations.

New Meta-Protocols

LP (Liquidity Provisioning)

  • Actions: add, remove, collect_fees
  • EVM: Uniswap V3 (Ethereum, Arbitrum, Optimism, Base, Polygon, BSC, Avalanche)
  • Solana: Raydium CLMM, Orca Whirlpools, Meteora

Lend (Lending/Borrowing)

  • Actions: supply, withdraw, borrow, repay
  • EVM: AAVE V3, Compound V3 (USDC/WETH markets)
  • Solana: Kamino, Marginfi, Solend

Perps (Perpetuals Trading)

  • Actions: open_long, open_short, close, increase, decrease
  • EVM: GMX V2 (Arbitrum, Avalanche), Hyperliquid, Lighter
  • Solana: Jupiter Perps, Drift Protocol

Bet (Prediction Markets)

  • Actions: buy, sell, cancel
  • Protocols: Polymarket (Polygon)

Key Features

  • ERC20 Approval Bundling: All EVM DeFi operations automatically prepend the required erc20.approve rule with the exact amount constraint, enabling TSS to sign both approval and action in sequence
  • Multi-chain Address Registry: Centralized registries for DeFi protocol addresses per chain (chain/evm/defi_registry.go, chain/solana/defi_registry.go)
  • ABIs/IDLs: Added contract definitions for all supported protocols
  • Comprehensive Tests: 24+ new test cases covering all meta-protocols and error scenarios

Files Changed

New Files

  • chain/evm/defi_registry.go - EVM DeFi protocol addresses
  • chain/solana/defi_registry.go - Solana program IDs
  • chain/evm/abi/*.json - Uniswap V3, AAVE, Compound, GMX, Hyperliquid, Polymarket ABIs
  • idl/*.json - Raydium, Orca, Meteora, Kamino, Marginfi, Solend, Jupiter Perps, Drift IDLs
  • metarule/internal/defi/types.go - DeFi constants and helpers
  • metarule/internal/defi/constraints.go - Constraint parsing for DeFi rules
  • metarule/defi_test.go - Comprehensive test suite

Modified Files

  • metarule/metarule.go - Added lp, lend, perps, bet handlers
  • README.md - Documentation for DeFi meta-protocols

Testing

go build ./...
go test ./...
golangci-lint run ./...

All tests pass (24 new DeFi tests + existing tests).

Summary by CodeRabbit

  • New Features

    • Added broad DeFi meta-protocol support: LP, lending, perpetuals, and prediction markets across Ethereum, Arbitrum, Polygon, and Solana; new protocol integrations and bridge/router planning.
    • Published new contract/program interfaces and protocol registries for popular DeFi protocols.
  • Documentation

    • Expanded README with DeFi Operations and meta-protocol examples.
    • Large update to protocol resource documentation and supported routes.
  • Tests

    • Added extensive unit tests covering multi-chain DeFi rule formatting and sequencing.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 6, 2026

Warning

Rate limit exceeded

@jpthor has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 17 minutes and 47 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 0f50e40 and e5107ca.

📒 Files selected for processing (29)
  • .cursor/plans/canonical_bridge_router_c7ea46e1.plan.md
  • .cursor/plans/defi_recipes_implementation_8fba4444.plan.md
  • README.md
  • RESOURCES.md
  • chain/evm/abi/aaveV3_pool.json
  • chain/evm/abi/compoundV3_comet.json
  • chain/evm/abi/gmxV2_exchange_router.json
  • chain/evm/abi/hyperliquid_bridge.json
  • chain/evm/abi/uniswapV3_nonfungible_position_manager.json
  • chain/evm/defi_registry.go
  • chain/solana/defi_registry.go
  • chain/utxo/dash/chain.go
  • chain/utxo/dash/decode.go
  • chain/utxo/dash/protocol.go
  • chain/xrpl/chain.go
  • chain/xrpl/protocol.go
  • engine/utxo/dogecoin/dogecoin.go
  • engine/utxo/litecoin/litecoin.go
  • idl/drift_protocol.json
  • idl/jupiter_perpetuals.json
  • idl/kamino_lending.json
  • idl/orca_whirlpool.json
  • idl/raydium_clmm.json
  • metarule/defi_test.go
  • metarule/internal/defi/constraints.go
  • metarule/internal/defi/types.go
  • metarule/metarule.go
  • metarule/metarule_test.go
  • types/transaction.go

Walkthrough

Adds comprehensive DeFi support: planning docs for a canonical bridge router, new EVM ABIs and Solana IDLs, chain registries, metarule DeFi types/constraint parsing and routing with tests, large RESOURCES expansions, and minor formatting tweaks across several chains and engines.

Changes

Cohort / File(s) Summary
Planning Documents
.cursor/plans/canonical_bridge_router_c7ea46e1.plan.md, .cursor/plans/defi_recipes_implementation_8fba4444.plan.md
New architectural and implementation plans for a canonical bridge router and DeFi recipes/meta-protocols (phased roadmaps, provider/resolver proposals).
Documentation & Resources
README.md, RESOURCES.md
Expanded README with DeFi meta-protocols and examples; major RESOURCES.md additions introducing many new Ethereum protocol resources and example policy constraints.
EVM ABI Definitions
chain/evm/abi/aaveV3_pool.json, chain/evm/abi/compoundV3_comet.json, chain/evm/abi/gmxV2_exchange_router.json, chain/evm/abi/hyperliquid_bridge.json, chain/evm/abi/polymarket_ctf.json, chain/evm/abi/polymarket_ctf_exchange.json, chain/evm/abi/uniswapV3_nonfungible_position_manager.json
Added multiple new ABI JSON files describing public contract interfaces for Aave V3, Compound V3 Comet, GMX V2, Hyperliquid Bridge, Polymarket CTF/exchange, and UniswapV3 NFT position manager.
Protocol Registries
chain/evm/defi_registry.go, chain/solana/defi_registry.go
New EVM and Solana registries mapping chains/protocols to addresses/program IDs with getter accessors.
Solana IDLs
idl/drift_protocol.json, idl/jupiter_perpetuals.json, idl/kamino_lending.json, idl/orca_whirlpool.json, idl/raydium_clmm.json
Added five Solana IDL files defining instruction/account/argument schemas for perps, lending, and LP programs.
Metarule DeFi Integration
metarule/internal/defi/types.go, metarule/internal/defi/constraints.go, metarule/metarule.go, metarule/defi_test.go, metarule/metarule_test.go
New DeFi protocol/type definitions and action enums; constraint parsers for lp/lend/perps/bet; extended metarule routing to handle DeFi flows including automatic ERC20 approval sequencing; comprehensive tests added/updated.
Chain & Engine Formatting
chain/utxo/dash/*, chain/xrpl/*, engine/utxo/dogecoin/dogecoin.go, engine/utxo/litecoin/litecoin.go, types/transaction.go
Minor whitespace/formatting-only changes (trailing newlines) with no behavioral changes.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 39.66% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main addition of DeFi meta-protocols, which is the primary focus of the changeset.

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.

Copy link
Contributor

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
RESOURCES.md (2)

1-7196: Pipeline failure: RESOURCES.md requires regeneration.

The CI reports this file is out of date. Run the generator command to update:

go run cmd/generator/main.go --output RESOURCES.md

27-43: Invalid JSON in example policy rules (trailing commas).

The example JSON blocks contain trailing commas before closing braces, which is invalid JSON syntax:

{
  "constraints": {
    "amount": {
      "type": "fixed",
      "value": "example_value"
    },

  }  // <- trailing comma before this brace
}

This pattern appears throughout the file (e.g., lines 40-42, 77-79, etc.). If this file is auto-generated, the generator template needs fixing.

🤖 Fix all issues with AI Agents
In @chain/evm/defi_registry.go:
- Around line 12-61: The GMX V2 ExchangeRouter addresses in the
GMXV2ExchangeRouter map are outdated; update the Arbitrum entry in
GMXV2ExchangeRouter to "0x602b805EedddBbD9ddff44A7dcBD46cb07849685" and the
Avalanche entry to "0xFa843af557824Be5127eaCB3c4B5D86EADEB73A1". While editing,
double-check the GMXV2OrderVault map and the CompoundV3CometUSDC and AaveV3Pool
maps against official sources and correct any mismatches you find, making
changes directly to those map entries (GMXV2OrderVault, CompoundV3CometUSDC,
AaveV3Pool) to reflect current deployments.

In @chain/solana/defi_registry.go:
- Around line 8-38: The Kamino lending program ID constant
KaminoLendingProgramID is using the wrong Base58 string; update the value passed
to solana.MustPublicKeyFromBase58 in the KaminoLendingProgramID declaration to
the official mainnet program ID "GzFgdRJXmawPhGeBsyRCDLx4jAKPsvbUqoqitzppkzkW"
so KaminoLendingProgramID is constructed from the correct public key.

In @idl/kamino_lending.json:
- Around line 1-76: The IDL metadata contains the wrong program address; update
metadata.address to the official Kamino Lending program ID. Edit the JSON's
metadata.address field (symbol: metadata.address in idl/kamino_lending.json) and
replace "KLend2g3cP87ber41GYr72yfE9j6eBJYwRqVNMi6mHL" with
"GzFgdRJXmawPhGeBsyRCDLx4jAKPsvbUqoqitzppkzkW"; leave the existing instruction
definitions (deposit, withdraw, borrow, repay) and their account/arg structures
unchanged. Ensure the file remains valid JSON after the replacement.

In @metarule/internal/defi/constraints.go:
- Around line 1-238: The helper constructors Fixed, Any, Min, and Max are
unused—either remove them or mark them as exported/documented for external use
(e.g., add a comment above Fixed/Any/Min/Max explaining intended public API
usage) and update tests to use them if you keep them; also add a brief comment
in ParseLendConstraints or above LendConstraints noting that asset and amount
are required intentionally (stricter validation), and add short field comments
to LPConstraints and PerpsConstraints to match the inline comments style used in
BetConstraints so struct documentation is consistent.
🧹 Nitpick comments (12)
chain/utxo/dash/protocol.go (1)

67-156: Clarify the purpose of creating two parameter maps with identical values.

Lines 79-86 create both params (used for constraint checking) and displayParams (returned) with nearly identical content—only the amount differs (as *big.Int vs. string). If both maps are necessary, document the distinction; if not, avoid the duplication. If displayParams is intended for user-facing output, it should handle unit conversion for duffs explicitly.

For example:

  • Are both needed, or should only the return value be used?
  • Should displayParams["amount"] apply a duffs-to-DASH conversion (if applicable)?
  • Why not return a single, well-typed structure or comment the trade-off?
.cursor/plans/defi_recipes_implementation_8fba4444.plan.md (2)

121-121: Markdown table formatting is broken.

The table content appears on a single line without proper row separators. This will render incorrectly in most Markdown viewers.

🔎 Proposed fix for table formatting
-**Supported Protocols:**| Protocol | Chain | Type ||----------|-------|------|| Uniswap V3 | EVM (Ethereum, Arbitrum, Base, etc.) | Concentrated liquidity || Raydium CLMM | Solana | Concentrated liquidity || Orca Whirlpools | Solana | Concentrated liquidity || Meteora | Solana | Dynamic pools |**Action mappings (EVM - UniswapV3):**
+**Supported Protocols:**
+
+| Protocol | Chain | Type |
+|----------|-------|------|
+| Uniswap V3 | EVM (Ethereum, Arbitrum, Base, etc.) | Concentrated liquidity |
+| Raydium CLMM | Solana | Concentrated liquidity |
+| Orca Whirlpools | Solana | Concentrated liquidity |
+| Meteora | Solana | Dynamic pools |
+
+**Action mappings (EVM - UniswapV3):**

117-118: Minor: Inconsistent indentation in parameter list.

min_amount1 has extra leading indentation compared to min_amount0.

🔎 Proposed fix
     - min_amount0: uint256 (slippage protection for add/remove)
-        - min_amount1: uint256
+    - min_amount1: uint256
metarule/metarule.go (3)

355-515: DeFi EVM handlers: LP/lend/perps/bet wiring looks correct; consider tightening a few constraint defaults

The new EVM DeFi handlers are wired coherently (chain resolution, registry lookups, address helpers, approve‑then‑action sequencing). A few places are more permissive than necessary for high‑risk operations:

  • LP add (handleEVMLP, Uniswap V3): amount0/amount1 are optional in getLPConstraints and default to anyConstraint(). If the caller omits them, both the erc20.approve and mint rules allow unbounded amounts. Given the intent to “prepend exact‑amount approve rules”, it would be safer to treat amount0/amount1 as required for action == "add" (and possibly min_amount*), or at least error when they are left as ANY for this action.
  • Lend / perps: getLendConstraints and getPerpsConstraints correctly enforce the minimum required fields and default the rest to ANY. That matches existing meta‑rule style, but for flows that mint approvals (Aave/Compound supply, GMX collateral) you may want to ensure amount/collateral_delta are not left as unconstrained ANY.
  • Polymarket bet: the single‑order fillOrder and cancelOrder rules correctly bind order.tokenId and order.maker (and order.side for buy/sell). The batch variants (fillOrders, cancelOrders) currently expose the orders arrays as fully ANY, which makes the policy strictly more permissive than the single‑order case. If you want bet rules to stay tightly scoped per market/maker, consider either dropping the batch methods from this meta‑protocol or documenting that bet.* intentionally allows arbitrary batch fills/cancels.

Functionally this is all sound and matches the tests; the above are about tightening policy defaults on sensitive DeFi actions rather than fixing bugs.

Also applies to: 2035-3332


247-365: Solana DeFi handlers: perps side/direction not bound to open_long / open_short actions

The new Solana LP/lend handlers are straightforward and consistent with the added IDLs. For perps:

  • EVM perps (handleEVMPerps) derive isLong/isBid directly from action and fix those fields in the GMX/Hyperliquid rules.
  • Solana perps (handleSolanaPerps) for jupiter_perps and drift leave arg_side, arg_direction, and arg_reduceOnly as ANY for all actions, so open_long, open_short, and close all share identical rule shapes.

That means the meta‑rule cannot enforce “long vs short vs close” semantics on Solana the way it does on EVM; it relies entirely on downstream code to set those fields correctly at execution time.

If you want parity and stronger safety, consider:

  • For jupiter_perps: fix arg_side based on action (e.g., "long" vs "short" or the numeric convention the program expects).
  • For drift: map action into appropriate arg_direction and arg_reduceOnly constraints for opens vs closes.

This keeps the meta‑protocol’s semantics aligned across chains and reduces the chance of a policy that intends “long‑only” silently allowing shorts or non‑reduce‑only closes.

Also applies to: 2520-2840


3005-3243: Constraint parsers: required vs optional fields are sensible; might strengthen LP amount requirements

The new constraint structs (lpConstraints, lendConstraints, perpsConstraints, betConstraints) and their parsers correctly:

  • Enforce presence of critical fields (action, protocol, plus asset/amount where needed).
  • Default all other missing fields to anyConstraint() to avoid nil dereferences downstream.

Only minor tightening worth considering:

  • For LP add actions, treat amount0/amount1 as required instead of optional, since they drive both approvals and mint bounds.
  • Optionally enforce that asset must be FIXED (not just non‑nil) in the contexts where you immediately call GetFixedValue() and expect an address (you already do this for several paths, but centralizing the validation in the parser could simplify handlers).

Otherwise the parsing layer looks robust and matches how the handlers consume these constraints.

.cursor/plans/canonical_bridge_router_c7ea46e1.plan.md (2)

160-173: Add language to fenced code block to satisfy markdownlint

The file‑structure code block currently uses bare triple backticks, which triggers MD040 (“fenced code blocks should have a language specified”).

Recommend adding an explicit language, e.g.:

Proposed markdown tweak
-```
+```text
 recipes/sdk/bridge/
 ├── types.go           # BridgeProvider interface, request/response types
 ├── router.go          # BridgeRouter with priority selection
 ├── bridge.go          # Package docs & convenience functions
 ├── lifi.go            # LiFi bridge provider
 ├── native.go          # Native L2 bridge provider
 ├── native_arbitrum.go # Arbitrum Gateway implementation
 ├── native_base.go     # Base Standard Bridge implementation
 ├── native_optimism.go # Optimism Standard Bridge implementation
 └── router_test.go     # Tests
-```
+```
</details>

---

`4-40`: **Plan status vs code: double‑check `metarule-bridge` “completed” flag**

The plan lists `metarule-bridge` (“Add bridge metaProtocol to metarule/metarule.go”) as `status: completed`. In the metarule constants shown in this PR, only `send`, `swap`, `lp`, `lend`, `perps`, and `bet` are present.

If `bridge` was added in a different change or later removed, it might be worth adjusting this TODO’s status/comment so the plan reflects the current state and avoids confusion for future work.

</blockquote></details>
<details>
<summary>metarule/defi_test.go (1)</summary><blockquote>

`11-1086`: **DeFi meta‑protocol tests provide good coverage of new flows**

The new `defi_test.go` suite exercises:

- Happy paths for EVM LP (Uniswap V3), lend (Aave, Aave on Arbitrum), perps (GMX, Hyperliquid), Solana LP/lend/perps, and Polymarket bet buy/sell/cancel.
- Key safety properties like “approve before action” ordering and correct target contract addresses.
- Error cases for missing `action`/`protocol`, unsupported protocols/actions, and Polymarket on the wrong chain.

This is a solid baseline. If you want to harden things further later, you could add focused tests for:

- Aave/Compound `repay`/`withdraw` branches.
- GMX `close` and Hyperliquid `adjust_margin`.
- Solana perps edge cases (e.g., verifying side/direction mapping once constrained).

But as written, the tests align well with the handlers.

</blockquote></details>
<details>
<summary>chain/solana/defi_registry.go (2)</summary><blockquote>

`59-97`: **Silent failure on unknown protocol may mask bugs.**

The getter functions return an empty `PublicKey{}` with `nil` error for unknown protocols (lines 69, 83, 95). This makes it difficult for callers to distinguish between "protocol not found" and a successful lookup.

Consider returning an error for unknown protocols to enable proper error handling:


<details>
<summary>🔎 Proposed fix</summary>

```diff
 func GetLPProgramID(protocol DeFiProtocol) (solana.PublicKey, error) {
 	switch protocol {
 	case ProtocolRaydium:
 		return RaydiumCLMMProgramID, nil
 	case ProtocolOrca:
 		return OrcaWhirlpoolProgramID, nil
 	case ProtocolMeteora:
 		return MeteoraProgramID, nil
 	default:
-		return solana.PublicKey{}, nil
+		return solana.PublicKey{}, fmt.Errorf("unknown LP protocol: %s", protocol)
 	}
 }

Apply the same pattern to GetLendingProgramID and GetPerpsProgramID.


40-57: Type duplication with metarule/internal/defi/types.go.

DeFiProtocol (line 41) and its constants duplicate Protocol from metarule/internal/defi/types.go (lines 8-24 in that file). This creates maintenance burden and potential for drift.

Consider either:

  1. Importing and using defi.Protocol here, or
  2. Creating a shared package for protocol definitions
chain/evm/defi_registry.go (1)

63-183: Inconsistent error message capitalization.

Error messages have inconsistent capitalization patterns:

  • Line 67: "UniswapV3 Position Manager" (title case)
  • Line 76: "AAVE V3 Pool" (all caps for AAVE)
  • Line 95: "compound V3" (lowercase)
  • Line 122: "hyperliquid bridge" (lowercase)
  • Line 153: "polymarket CTF Exchange" (mixed)

Consider standardizing to match protocol branding (e.g., "Compound V3", "Hyperliquid", "Polymarket").

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e034323 and 0fa817b.

📒 Files selected for processing (31)
  • .cursor/plans/canonical_bridge_router_c7ea46e1.plan.md
  • .cursor/plans/defi_recipes_implementation_8fba4444.plan.md
  • README.md
  • RESOURCES.md
  • chain/evm/abi/aaveV3_pool.json
  • chain/evm/abi/compoundV3_comet.json
  • chain/evm/abi/gmxV2_exchange_router.json
  • chain/evm/abi/hyperliquid_bridge.json
  • chain/evm/abi/polymarket_ctf.json
  • chain/evm/abi/polymarket_ctf_exchange.json
  • chain/evm/abi/uniswapV3_nonfungible_position_manager.json
  • chain/evm/defi_registry.go
  • chain/solana/defi_registry.go
  • chain/utxo/dash/chain.go
  • chain/utxo/dash/decode.go
  • chain/utxo/dash/protocol.go
  • chain/xrpl/chain.go
  • chain/xrpl/protocol.go
  • engine/utxo/dogecoin/dogecoin.go
  • engine/utxo/litecoin/litecoin.go
  • idl/drift_protocol.json
  • idl/jupiter_perpetuals.json
  • idl/kamino_lending.json
  • idl/orca_whirlpool.json
  • idl/raydium_clmm.json
  • metarule/defi_test.go
  • metarule/internal/defi/constraints.go
  • metarule/internal/defi/types.go
  • metarule/metarule.go
  • metarule/metarule_test.go
  • types/transaction.go
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-09-16T15:18:29.097Z
Learnt from: neavra
Repo: vultisig/recipes PR: 123
File: engine/xrpl/xrpl.go:41-51
Timestamp: 2025-09-16T15:18:29.097Z
Learning: XRPL engine should support multiple functions including "send" and "thorchain_swap" rather than being restricted to just "send".

Applied to files:

  • README.md
📚 Learning: 2025-07-28T17:33:10.162Z
Learnt from: webpiratt
Repo: vultisig/recipes PR: 50
File: ethereum/ethereum.go:165-166
Timestamp: 2025-07-28T17:33:10.162Z
Learning: The Protocol interface in types/protocol.go includes a ChainID() string method, so calling ChainID() on any Protocol implementation (like NewETH()) is valid and will not cause compilation errors.

Applied to files:

  • chain/utxo/dash/chain.go
  • metarule/metarule.go
  • chain/solana/defi_registry.go
🧬 Code graph analysis (5)
metarule/defi_test.go (3)
metarule/metarule.go (1)
  • NewMetaRule (21-23)
types/constraint.pb.go (2)
  • ConstraintType_CONSTRAINT_TYPE_FIXED (29-29)
  • ConstraintType_CONSTRAINT_TYPE_MAX (30-30)
sdk/tron/tron.go (1)
  • Value (67-71)
metarule/metarule_test.go (2)
types/rule.pb.go (1)
  • TargetType_TARGET_TYPE_ADDRESS (28-28)
types/constraint.pb.go (1)
  • ConstraintType_CONSTRAINT_TYPE_FIXED (29-29)
metarule/internal/defi/types.go (1)
chain/solana/defi_registry.go (8)
  • ProtocolRaydium (45-45)
  • ProtocolOrca (46-46)
  • ProtocolMeteora (47-47)
  • ProtocolKamino (50-50)
  • ProtocolMarginfi (51-51)
  • ProtocolSolend (52-52)
  • ProtocolJupiterPerps (55-55)
  • ProtocolDrift (56-56)
metarule/metarule.go (3)
types/constraint.pb.go (3)
  • Constraint (145-165)
  • Constraint (178-178)
  • Constraint (193-195)
types/rule.pb.go (2)
  • Effect_EFFECT_ALLOW (78-78)
  • TargetType_TARGET_TYPE_ADDRESS (28-28)
chain/evm/defi_registry.go (3)
  • GetPolymarketCTFExchange (150-156)
  • GetPolymarketUSDC (177-183)
  • GetPolymarketCTF (168-174)
chain/solana/defi_registry.go (1)
metarule/internal/defi/types.go (8)
  • ProtocolRaydium (9-9)
  • ProtocolOrca (10-10)
  • ProtocolMeteora (11-11)
  • ProtocolKamino (16-16)
  • ProtocolMarginfi (17-17)
  • ProtocolSolend (18-18)
  • ProtocolJupiterPerps (24-24)
  • ProtocolDrift (25-25)
🪛 GitHub Actions: Check Resources Documentation
RESOURCES.md

[error] 1-1: RESOURCES.md is out of date. Please run 'go run cmd/generator/main.go --output RESOURCES.md' and commit the changes.

🪛 LanguageTool
.cursor/plans/defi_recipes_implementation_8fba4444.plan.md

[grammar] ~242-~242: Ensure spelling is correct
Context: ...V3_nonfungible_position_manager.json- UniswapV3 LP positions -aaveV3_pool.json` - AAV...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
.cursor/plans/canonical_bridge_router_c7ea46e1.plan.md

162-162: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🔇 Additional comments (24)
engine/utxo/dogecoin/dogecoin.go (1)

39-43: Formatting improvement approved.

Adding a trailing newline at the end of the file aligns with Go conventions and linter standards.

chain/utxo/dash/decode.go (1)

120-124: Formatting improvement approved.

Adding a trailing newline at the end of the file aligns with Go conventions.

chain/xrpl/chain.go (1)

189-196: Formatting improvement approved.

Adding a trailing newline at the end of the file aligns with Go conventions and linter standards.

chain/utxo/dash/chain.go (1)

96-101: Proper file formatting.

The addition of a trailing newline follows Go conventions. No logic changes.

chain/evm/abi/polymarket_ctf.json (1)

1-13: Polymarket CTF ABI integration is correctly implemented.

Both ABI files exist and are properly integrated:

  • polymarket_ctf.json contains setApprovalForAll
  • polymarket_ctf_exchange.json contains fillOrder and fillOrders
  • DeFi registry defines all required contracts with getter functions
  • Metarule handler correctly chains the three-step flow: CTF approval → ERC20 approval → order filling
README.md (1)

117-143: Remove unsupported Lighter protocol and correct perps action names in DeFi meta-protocols table.

The documentation lists protocols and actions that don't match the actual implementation:

  1. Lighter (EVM) is not implemented — Although ProtocolLighter is defined in metarule/internal/defi/types.go, the handleEVMPerps function only supports "gmx" and "hyperliquid" protocols. Remove Lighter from the table.

  2. Perps actions are incorrect — The README lists increase and decrease actions, but the implementation only supports open_long, open_short, close, and adjust_margin. Update the table to reflect the actual supported actions.

Corrected table snippet
| **perps** | `open_long`, `open_short`, `close`, `adjust_margin` | GMX V2, Hyperliquid (EVM), Jupiter Perps, Drift (Solana) |

Likely an incorrect or invalid review comment.

idl/raydium_clmm.json (1)

1-96: LGTM!

The Raydium CLMM IDL correctly defines the concentrated liquidity operations needed for the LP meta-protocol. The slippage protection parameters are appropriately named (amount*Max for deposits, amount*Min for withdrawals), and the account structures are comprehensive.

.cursor/plans/defi_recipes_implementation_8fba4444.plan.md (1)

165-165: Action inconsistency between plan and PR description.

The plan shows adjust_margin as a perps action, but the PR description lists increase and decrease as separate actions. Ensure alignment between the plan and implementation.

chain/evm/abi/aaveV3_pool.json (1)

1-106: LGTM!

The AAVE V3 Pool ABI correctly defines the core lending operations (supply, withdraw, borrow, repay) and includes useful additions like permit-based variants and getUserAccountData for health factor checks. This covers all actions needed for the lend meta-protocol.

chain/evm/abi/gmxV2_exchange_router.json (1)

1-83: LGTM!

The GMX V2 Exchange Router ABI is well-structured with comprehensive order parameters. The payable state mutability correctly reflects GMX's execution fee requirements. The multicall function will be useful for batching approval and order creation operations.

chain/evm/abi/hyperliquid_bridge.json (2)

32-57: Verify if order and cancel functions belong in the bridge ABI.

The file is named hyperliquid_bridge.json, but includes trading functions (order, cancel) alongside bridge operations (batchedDepositWithPermit, initiateWithdrawal, finalizeWithdrawal). The PR objectives note that Hyperliquid uses EIP-712 signing on its custom L1 and initial support is via the EVM bridge for deposits/withdrawals only.

Consider whether these trading functions are accessible via the EVM bridge or if they should be in a separate ABI for the native Hyperliquid interface.


3-5: Note: uint64 type for USD amounts.

The ABI uses uint64 for USD amounts instead of the typical uint256. This aligns with Hyperliquid's 6-decimal precision model but differs from most EVM DeFi conventions. Ensure downstream handlers account for this precision difference.

idl/drift_protocol.json (1)

1-62: Drift Protocol IDL is well-structured and follows Anchor conventions.

The program address (dRiftyHA39MWEi3m9aunc5MzRF1JYuBsbn6VPcn33UH) is correct for Drift Protocol v2 on Solana mainnet. The subset of instructions (placePerpOrder, deposit, withdraw) is appropriate for the perps meta-protocol use cases. Account mutability flags are consistent with expected behavior—notably, the state account is mutable in withdraw but immutable in deposit, which is intentional.

metarule/metarule.go (2)

441-507: EVM swap: approve‑then‑swap sequencing and router constraints look solid

The updated EVM swap path now prepends a bounded erc20.approve rule (spender = 1inch router or THORCHAIN router magic constant, amount = from_amount) before the actual swap rule, and the test adjustment for TestTryFormat_EvmSwap matches this behavior. This sequencing should work well for clients that need two sequential signatures (approve, then swap), and the router constraint reuses existing magic constants correctly for the ThorChain path.

No functional issues spotted here.


3249-3332: Helper mappings and ERC20 approve helper are consistent with usage

The new helpers (getUniswapV3PositionManager, getAaveV3Pool, getCompoundV3Comet, getGMXV2ExchangeRouter, getHyperliquidBridge, createERC20ApproveRule) are internally consistent:

  • Chain → address maps align with the chains actually used in tests.
  • Error messages are explicit for unsupported chains, which will surface cleanly through TryFormat.
  • createERC20ApproveRule centralizes the approve pattern and is used consistently by LP, lend, perps, and bet flows.

No issues here.

idl/orca_whirlpool.json (1)

1-66: Orca Whirlpool IDL matches Solana LP handler usage

The IDL for orca_whirlpool cleanly exposes increaseLiquidity, decreaseLiquidity, and collectFees with account and argument names that align with handleSolanaLP (arg_liquidityAmount, arg_tokenMaxA/B, arg_tokenMinA/B). Program address also matches the handler’s hardcoded ID.

Looks good.

metarule/metarule_test.go (1)

753-879: EVM swap test correctly updated for approve‑then‑swap flow

The TestTryFormat_EvmSwap changes accurately reflect the new behavior:

  • Asserting the first rule is ethereum.erc20.approve targeting USDC with fixed amount and spender matching the 1inch router.
  • Asserting the second rule is the 1inch swap with the expected router address and parameter set.

This gives good coverage of the new two‑tx sequence.

chain/evm/abi/polymarket_ctf_exchange.json (1)

1-116: Polymarket CTF Exchange ABI aligns with bet meta‑protocol

The ABI for polymarket_ctf_exchange matches how handleEVMBet constructs rules:

  • Functions and names (fillOrder, fillOrders, cancelOrder, cancelOrders) are present.
  • The Order tuple exposes tokenId, maker, side, and signature fields with the names referenced by the metarule.
  • Batch variants use orders and fillAmounts as expected.

No issues from the ABI side.

chain/evm/abi/compoundV3_comet.json (1)

1-106: Compound V3 Comet ABI matches lend handler expectations

The compoundV3_comet ABI exposes:

  • supply(address asset, uint256 amount) and withdraw(address asset, uint256 amount) exactly as used in handleEVMLend.
  • Additional helpers (balanceOf, borrowBalanceOf, collateralBalanceOf, etc.) that can be constrained later if needed.

Interface and naming are consistent with the new lend rules.

chain/evm/abi/uniswapV3_nonfungible_position_manager.json (1)

1-137: LGTM — Standard Uniswap V3 Position Manager ABI.

The ABI correctly defines the core functions for managing liquidity positions: mint, increaseLiquidity, decreaseLiquidity, collect, burn, positions, and multicall. The struct types and state mutability annotations align with the official Uniswap V3 interface.

metarule/internal/defi/types.go (2)

53-58: Perps action naming may differ from PR objectives.

The PR summary mentions perps actions as "open_long, open_short, close, increase, decrease" but the code defines PerpsActionAdjustMargin (line 57) instead of separate increase and decrease actions. Verify this consolidated action is intentional.


1-87: LGTM — Clean protocol taxonomy with ecosystem helpers.

The type definitions provide a clear classification of DeFi protocols and actions. The IsEVMProtocol and IsSolanaProtocol helper functions (lines 70-86) enable clean routing logic.

chain/evm/defi_registry.go (1)

81-98: Good market selector pattern for Compound V3.

The GetCompoundV3Comet function (lines 81-98) handles case-insensitive market selection cleanly. This is a good pattern for user-facing inputs.

idl/jupiter_perpetuals.json (1)

1-130: LGTM — Well-structured Jupiter Perpetuals IDL.

The IDL correctly defines the perpetuals instructions with appropriate account metadata and argument types. The program address (line 5) matches the JupiterPerpsProgramID in the Solana registry, ensuring consistency.

Copy link
Contributor

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

🧹 Nitpick comments (4)
metarule/internal/defi/constraints.go (3)

9-60: Consider adding field comments for consistency.

The LPConstraints struct and ParseLPConstraints function are well-structured. However, BetConstraints (lines 160-167) includes inline field comments while this struct does not. Consider adding brief comments to each field for consistency and better documentation.


62-107: Document stricter validation requirements.

ParseLendConstraints validates four required fields (Action, Protocol, Asset, Amount) compared to only two for LP and Perps parsers. While this stricter validation is appropriate for lending operations, consider adding a brief comment above the struct or in the parser explaining why Asset and Amount are mandatory for lending. Also, add inline field comments to match the style in BetConstraints (lines 160-167).


109-157: Add field comments for consistency.

The PerpsConstraints struct and parser are well-implemented. Consider adding inline field comments similar to BetConstraints (lines 160-167) to maintain consistent documentation across all constraint types.

chain/solana/defi_registry.go (1)

59-97: Return explicit errors for unsupported protocols.

The getter functions (GetLPProgramID, GetLendingProgramID, GetPerpsProgramID) currently return an empty PublicKey with nil error for unsupported protocols (lines 69, 83, 95). This could lead to silent failures if callers don't explicitly check whether the returned key is empty. Since the function signatures include an error return, consider returning an explicit error instead.

🔎 Proposed fix for explicit error handling
 func GetLPProgramID(protocol DeFiProtocol) (solana.PublicKey, error) {
 	switch protocol {
 	case ProtocolRaydium:
 		return RaydiumCLMMProgramID, nil
 	case ProtocolOrca:
 		return OrcaWhirlpoolProgramID, nil
 	case ProtocolMeteora:
 		return MeteoraProgramID, nil
 	default:
-		return solana.PublicKey{}, nil
+		return solana.PublicKey{}, fmt.Errorf("unsupported LP protocol: %s", protocol)
 	}
 }

Apply similar changes to GetLendingProgramID and GetPerpsProgramID. You'll also need to import "fmt".

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0fa817b and 0f50e40.

📒 Files selected for processing (4)
  • chain/evm/defi_registry.go
  • chain/solana/defi_registry.go
  • idl/kamino_lending.json
  • metarule/internal/defi/constraints.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • idl/kamino_lending.json
  • chain/evm/defi_registry.go
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-07-28T17:33:10.162Z
Learnt from: webpiratt
Repo: vultisig/recipes PR: 50
File: ethereum/ethereum.go:165-166
Timestamp: 2025-07-28T17:33:10.162Z
Learning: The Protocol interface in types/protocol.go includes a ChainID() string method, so calling ChainID() on any Protocol implementation (like NewETH()) is valid and will not cause compilation errors.

Applied to files:

  • chain/solana/defi_registry.go
🧬 Code graph analysis (2)
chain/solana/defi_registry.go (1)
metarule/internal/defi/types.go (8)
  • ProtocolRaydium (9-9)
  • ProtocolOrca (10-10)
  • ProtocolMeteora (11-11)
  • ProtocolKamino (16-16)
  • ProtocolMarginfi (17-17)
  • ProtocolSolend (18-18)
  • ProtocolJupiterPerps (24-24)
  • ProtocolDrift (25-25)
metarule/internal/defi/constraints.go (1)
metarule/internal/defi/types.go (1)
  • Protocol (4-4)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: check-resources
🔇 Additional comments (4)
metarule/internal/defi/constraints.go (1)

159-198: LGTM! Good documentation model.

The BetConstraints struct and parser are well-implemented with clear inline field comments. This serves as a good documentation model for the other constraint types.

chain/solana/defi_registry.go (3)

7-17: LGTM! LP program IDs verified.

The LP protocol program IDs for Raydium CLMM, Orca Whirlpools, and Meteora have been verified as correct per previous review. Using MustPublicKeyFromBase58 is appropriate for these compile-time constants.


19-29: ✅ Kamino program ID corrected!

The Kamino Lending program ID has been updated to the correct official mainnet address (GzFgdRJXmawPhGeBsyRCDLx4jAKPsvbUqoqitzppkzkW), addressing the issue raised in the previous review. Marginfi and Solend program IDs are also verified as correct.


31-38: LGTM! Perps program IDs verified.

The perpetuals protocol program IDs for Jupiter Perps and Drift have been verified as correct per previous review.

@jpthor
Copy link
Collaborator Author

jpthor commented Jan 7, 2026

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 7, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

jpthor added 2 commits January 7, 2026 13:07
Add high-level DeFi recipe meta-protocols that transform into low-level
ABI/IDL calls:

Meta-protocols:
- lp: Liquidity pool management (add/remove/collect_fees)
- lend: Lending protocol operations (supply/withdraw/borrow/repay)
- perps: Perpetual DEX trading (open_long/open_short/close/adjust_margin)
- bet: Prediction markets (buy/sell/cancel) - Polymarket on Polygon

EVM Protocols:
- UniswapV3 (LP) - Ethereum, Arbitrum, Optimism, Base, Polygon, BSC, Avalanche
- AAVE V3 (Lending) - Ethereum, Arbitrum, Optimism, Base, Polygon, Avalanche
- Compound V3 (Lending) - Ethereum, Arbitrum, Base, Polygon
- GMX V2 (Perps) - Arbitrum, Avalanche
- Hyperliquid (Perps) - Arbitrum bridge
- Polymarket (Betting) - Polygon

Solana Protocols (IDLs added):
- Raydium CLMM (LP)
- Orca Whirlpools (LP)
- Kamino (Lending)
- Jupiter Perps (Perps)
- Drift Protocol (Perps)

New files:
- chain/evm/defi_registry.go - EVM protocol addresses per chain
- chain/solana/defi_registry.go - Solana program IDs
- chain/evm/abi/*.json - Protocol ABIs
- idl/*.json - Solana IDLs
- metarule/internal/defi/ - DeFi constraint types and helpers
- metarule/defi_test.go - Meta-protocol tests

The bet meta-protocol for Polymarket correctly handles:
- CTF.setApprovalForAll for conditional token transfers
- ERC20.approve for USDC collateral (buy only)
- CTFExchange.fillOrder with proper order.side mapping (0=buy, 1=sell)
- Update GMX V2 ExchangeRouter addresses to latest deployed contracts
- Fix Kamino lending program ID to official mainnet address
- Remove unused helper functions (Fixed, Any, Min, Max) from constraints.go
- Regenerate RESOURCES.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant