Skip to content

feat: add Rubicon CLMM (UniswapV3 fork, concentrated liquidity, 4 chains) - #1183

Open
bghughes wants to merge 1 commit into
VeloraDEX:masterfrom
RubiconDeFi:feat/add-rubicon-clmm
Open

feat: add Rubicon CLMM (UniswapV3 fork, concentrated liquidity, 4 chains)#1183
bghughes wants to merge 1 commit into
VeloraDEX:masterfrom
RubiconDeFi:feat/add-rubicon-clmm

Conversation

@bghughes

@bghughes bghughes commented May 19, 2026

Copy link
Copy Markdown

Summary

Adds Rubicon CLMM — Rubicon Finance's UniswapV3-fork concentrated-liquidity AMM — as a routable liquidity source via the existing generic UniswapV3 adapter. CLMM is deployed on Ethereum, Optimism, Arbitrum, and Base.

Scope

Config-only addition. CLMM is byte-identical to UniswapV3: pool swap() ABI, slot0() 7-word layout, tickBitmap(int16) selector, and QuoterV2 interface all match exactly. No src/dex/uniswap-v3/forks/<name>/ subfolder is needed.

Files changed (3 files, +135 / -0)

  • src/dex/uniswap-v3/config.ts — one new entry, RubiconCLMM, covering all four chains.
  • src/dex/uniswap-v3/uniswap-v3.ts — append 'RubiconCLMM' to the existing _.pick(UniswapV3Config, [...]) allowlist used by dexKeysWithNetwork. Without this, the generic UniswapV3 class wouldn't pick up the new config entry.
  • src/dex/uniswap-v3/uniswap-v3-e2e.test.ts — one describe('RubiconCLMM', ...) block with four chain sub-describes (Mainnet / Optimism / Arbitrum / Base), each using the file's existing testForNetwork() helper with WETH/USDC pairs that have been verified live on each chain.

Configuration

All Rubicon-deployed CLMM contracts:

Chain Factory SwapRouter (router) QuoterV2 (quoter) NPM (reference)
Mainnet 0xDf62D9e51d7c08360dcd41931A2e6B97FF8C73E8 0xA01a2b3A8c3Ac72b096781D0d4b38a773458dfcf 0xdf7e8987421F541C50f821f8Cf22A6bDA5e1E05b 0x3739488662524c8CdC0B41D2fA6A1BdF75434541
Optimism 0x53f64267EDE764C53ABEbCc768aD7A96c6006D8a 0x67cE9B668429942Ef440C2d9191a9a7521cD0806 0xA132BfedED5A84f164c9AD59147378651B39495a 0x001C8124f4D63A6B44C904A9eFF620DF1be702aB
Arbitrum 0x045B7012CbD158C1b48874310F985Adb48aA62ba 0x3739488662524c8CdC0B41D2fA6A1BdF75434541 0x22066f5A85076630CF9DEEB0A12186b73CD3284C 0x3c57834ab85F7d9F036ef1C3147817694171DC03
Base 0xB5E5A9e628FEF819150A6E5127aB481cee5d6Ca9 0x8814575bBFf6F7F8084A34b6776660CBC7344c3c 0xff53aA370D66459bf7672014EB3A279d342c5a8f 0xF75a94E360502618c838219f8954Ce8b7666b42F
  • stateMulticall and uniswapMulticall — reused per-chain from the existing UniswapV3 config entry. These are factory-agnostic UniV3-shape state readers — they read any UniV3-shape pool by address and work unchanged against CLMM pools because storage layout is identical.

  • supportedFees: SUPPORTED_FEES — CLMM uses the standard UniV3 fee tier set; all four tiers (100 / 500 / 3000 / 10000) have pools deployed across the chains.

  • Pool init code hash (same on all four chains, from RubiconDeFi/rubicon-clmm-internal → PoolAddress.sol:6):

    0xd3e7f58b9af034cfa7a0597e539bae7c6b393817a47a6fc1e1503cd6eaffe22a
    

On-chain verification

Every Rubicon-deployed address in this PR was verified on the respective chain via eth_getCode (live bytecode) and eth_call:

  • Factory: feeAmountTickSpacing(500) = 10 confirmed on all 4 chains.

  • Quoter / NPM / SwapRouter: factory() returns the matching CLMM factory on all 4 chains. (i.e. cross-referenced — none of them point at the wrong factory.)

  • Init code hash: CREATE2 reproduction of real WETH/USDC fee=500 pools matches actual factory.getPool() output:

    Chain Computed pool On-chain pool Match
    Mainnet 0x61c611769e2630983a8ea3dce9d90f24ab7a7fb6 same
    Optimism 0x8d046c46412a8afbf612ed046938e9858491ecbc same
    Arbitrum 0xee57310555a957cec1debb65b1e165d7c9ed700f same
    Base 0x002ce7bb4c5d130ed79c908217ae565f537148cf same
  • Provenance: factory.owner() returns the same Rubicon deployer (0x3204ac6f848e05557c6c7876e09059882e07962f) on all 4 chains — consistent canonical deployment.

(Verification script available at RubiconDeFi/rubicon-integrations:scripts/verify-clmm-pr.py if maintainers want to re-run.)

Address quirk (intentional)

0x3739488662524c8CdC0B41D2fA6A1BdF75434541 appears twice: as Mainnet NPM and as Arbitrum SwapRouter. Different bytecode, same CREATE2 address. Verified on-chain:

  • Mainnet 0x3739…4541 — 24,384 bytes, ERC721 selectors → NonfungiblePositionManager.
  • Arbitrum 0x3739…4541 — 12,070 bytes, multicall+wrap selectors → SwapRouter.

The collision is intentional and deterministic (same salt, different deployed bytecode per chain).

Local checks

pretty-quick, tsc, and eslint all pass via the repo's pre-commit hook chain.

Subgraph

Intentionally omitted from this PR. CLMM pool discovery in this lib is factory-event-based, so the subgraph URL is only used by getTopPoolsForToken ranking. Rubicon's hosted subgraph is being replaced by RubiconDeFi/rubicon-indexer; adding subgraphURL is a planned follow-up once that endpoint's public GraphQL surface is live.

Companion PR

This is the V3 counterpart of #1182 (Rubicon Aquila V2). Same Rubicon team, same verification methodology.

Links


Note

Medium Risk
Adds a new routable UniV3-style DEX keyed by new on-chain contract addresses; misconfigured addresses or init code hash could break pricing/routing on the affected networks.

Overview
Adds RubiconCLMM as a new UniswapV3-compatible DEX entry, wiring in per-network factory/router/quoter, multicall addresses, fee tiers, and the pool initHash in uniswap-v3/config.ts.

Updates UniswapV3.dexKeysWithNetwork to include RubiconCLMM so the generic UniswapV3 adapter discovers it, and extends uniswap-v3-e2e.test.ts with WETH/USDC E2E swap tests across Mainnet/Optimism/Arbitrum/Base.

Reviewed by Cursor Bugbot for commit 749cb74. Bugbot is set up for automated code reviews on this repo. Configure here.

…ins)

Adds Rubicon CLMM — Rubicon Finance's UniswapV3-fork concentrated-liquidity
AMM, byte-identical to UniV3 — as a routable liquidity source via the existing
generic UniswapV3 adapter. CLMM is deployed on Ethereum, Optimism, Arbitrum,
and Base.

This is a config-only change. CLMM's pool swap() ABI, slot0 layout, tickBitmap
selector, and QuoterV2 interface all match UniswapV3 exactly, so no
src/dex/uniswap-v3/forks/<name>/ subfolder is needed.

Pool init code hash (same on all chains, from RubiconDeFi/rubicon-clmm-internal
PoolAddress.sol:6):
  0xd3e7f58b9af034cfa7a0597e539bae7c6b393817a47a6fc1e1503cd6eaffe22a

Verified on-chain via CREATE2 reproduction against real WETH/USDC fee=500 pools:
  Mainnet:  0x61c611769e2630983a8ea3dce9d90f24ab7a7fb6 ✓
  Optimism: 0x8d046c46412a8afbf612ed046938e9858491ecbc ✓
  Arbitrum: 0xee57310555a957cec1debb65b1e165d7c9ed700f ✓
  Base:     0x002ce7bb4c5d130ed79c908217ae565f537148cf ✓

Every quoter/NPM/swap_router .factory() call cross-references the matching
CLMM factory; existing UniswapV3 stateMulticall + uniswapMulticall addresses
per chain are reused (factory-agnostic; reads any UniV3-shape pool).

CLMM Ethereum NPM (0x3739…4541) shares the same address as CLMM Arbitrum
SwapRouter — this is intentional, deterministic CREATE2 from a salt that
yields identical addresses across chains with different deployed bytecode
(Eth: 24,384b ERC721 NPM; Arb: 12,070b multicall SwapRouter). Verified on-chain.

Docs: https://docs.rubicon.finance/integrations
Contracts: https://github.com/RubiconDeFi/rubicon-clmm-internal
@bghughes

bghughes commented Jun 2, 2026

Copy link
Copy Markdown
Author

Hi @0xNazarii @KanievskyiDanylo 👋 — bumping this companion to #1182. It adds Rubicon's CLMM (UniswapV3-fork concentrated liquidity) across 4 chains; CI is passing and nothing's outstanding on my end. Glad to make any changes you'd like — thanks for the review!

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