Skip to content

fix: make v6 subgraph queries and dispair resolution work against RaindexV6 - #481

Open
hardyjosh wants to merge 1 commit into
masterfrom
2026-09-11-robinhood-chain
Open

fix: make v6 subgraph queries and dispair resolution work against RaindexV6#481
hardyjosh wants to merge 1 commit into
masterfrom
2026-09-11-robinhood-chain

Conversation

@hardyjosh

@hardyjosh hardyjosh commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Three things stopped the solver from trading a v6 orderbook on a chain whose only DEX is UniswapV3. All were hit end to end on Robinhood Chain (4663), and with this branch the solver now finds a UniswapV3 route there and fills a live Raindex v6 order.

Depends on rainlanguage/sushiswap#51 (chain 4663 support); the submodule bump points at that branch.

1. The v6 subgraph queries ask for an entity that no longer exists

config.example.yaml says the v5 and v6 subgraph schemas are identical and that the v6= prefix exists only to pick the order decoder. That is no longer true. The v6 schema renamed the orderbook entity:

v5 v6
Order.orderbook Order.raindex
orderbooks (root) raindices
orderbook_in / orderbook_not_in raindex_in / raindex_not_in
Deposit.orderbook, Withdrawal.orderbook, TradeVaultBalanceChange.orderbook .raindex

So every v6 query fails with Type `Order` has no field `orderbook` , which the solver surfaces as the much less obvious Failed to fetch orders / Received invalid response. getOrderbooks() silently returned an empty set for the same reason.

The three query builders now take a SubgraphVersions and select the v6 entity under an orderbook alias, so the response shape is byte-identical across versions and no consumer of SgOrder / SgTransaction had to move. Legacy behaviour is the default parameter value.

2. Dispair resolution assumes getters the RaindexV6 deployer does not have

resolveVersionContracts derives the interpreter and store by calling I_INTERPRETER() / I_STORE() on the configured deployer. The RaindexV6-era deployer (0x7219E7497e31DD99411C06Cab9AD9a155E23369c on 4663) exposes only five selectors:

0xa3869e14 parse2(bytes)
0x5514ca20 parsePragma1(bytes)
0x6f5aa28d describedByMetaV1()
0xb92d7553 buildIntegrityFunctionPointers()
0x01ffc9a7 supportsInterface(bytes4)

Both reads revert, contracts.v6 comes back undefined, and every order is skipped with Cannot trade as dispair addresses are not configured for order V4 trade — even though dispair is configured, which makes the message actively misleading.

contracts.<version>.interpreter and .store are now optional config overrides. When supplied they are used directly; otherwise the onchain reads happen exactly as before, so existing configs are untouched.

3. BASES_TO_CHECK_TRADES_AGAINST was indexed unguarded

getCounterpartyOrdersAgainstBaseTokens does BASES_TO_CHECK_TRADES_AGAINST[chainId].every(...). That map is typed { readonly [chainId: number]: Token[] } and getChainConfig does not validate it, so on any chain sushi has no routing bases for this throws a TypeError the first time intra-orderbook counterparties are enumerated. Guarded with ?? [].

Testing

  • npm run lint clean, npm run unit-test 1094 passed / 66 files.
  • New tests: v6 vs legacy entity selection and filter keys for all three query builders; resolveVersionContracts preferring configured interpreter/store (asserting the deployer is not read) and falling back per-field; getCounterpartyOrdersAgainstBaseTokens on a chain with no bases entry.
  • Each new test was checked against the unmutated code — e.g. reverting the ?? [] guard fails the new test with TypeError: Cannot read properties of undefined (reading 'every').
  • End to end on chain 4663: the solver quoted a live Raindex v6 order (maxOutput 10 USDG, ratio 0.000379593 WETH/USDG), routed 100% through the UniswapV3 0.01% WETH/USDG pool and cleared it twice via RouteProcessorRaindexV6ArbOrderTaker, emptying the 20 USDG vault.

🤖 Generated with Claude Code

https://claude.ai/code/session_01HiqQdxokJ4edjAFyAkN9G3

Summary by CodeRabbit

  • New Features

    • Added optional interpreter and store contract-address overrides for protocol versions v4–v6.
    • Added support for version-aware subgraph queries, including v6 orderbook and transaction schemas.
  • Bug Fixes

    • Improved contract resolution to use configured overrides and fall back to on-chain discovery when needed.
    • Prevented order filtering from failing on chains without configured routing base tokens.
  • Tests

    • Expanded coverage for contract overrides, subgraph versions, configuration parsing, and missing routing-token settings.

CI note

Deploy-Preview is red, but it is red on every one of the last 10 runs across every branch (gh run list --workflow deploy-preview.yml), including master. It dies 4s in with All subgraphs have indexing error from the preview env's own config, not from anything here. Every other check is green, including all 7 e2e fork chains and git-clean.

(e2e fork test (BASE) failed once on the first run and passed on rerun. Root cause is a pre-existing 1-in-256 flake in the harness, not this diff: test/utils.js randomUint256() returns a zero-padded 32-byte hex, but e2e.test.js wraps it in ethers.BigNumber.from(...), which strips a leading zero byte — so whenever the first random byte is 0x00 the v5 orderbook's bytes32 vaultId coder rejects it with incorrect data length. Worth fixing separately by keeping the vaultId as a padded hex string rather than a BigNumber.)

…ndexV6

Three things stopped the solver from trading a v6 orderbook on a chain whose
only DEX is UniswapV3. All were hit end to end on Robinhood Chain (4663).

1. The v6 subgraph queries ask for an entity that no longer exists.

config.example.yaml claims the v5 and v6 subgraph schemas are identical and
that the `v6=` prefix exists only to pick the order decoder. That is no longer
true: the v6 schema renamed the orderbook entity to `raindex`, along with
`orderbooks` -> `raindices` and the `orderbook_in` / `orderbook_not_in` filter
keys -> `raindex_in` / `raindex_not_in`. Every v6 query therefore failed with
"Type `Order` has no field `orderbook`", surfaced as the much less obvious
"Failed to fetch orders / Received invalid response".

The query builders now take the subgraph version and select the v6 entity under
an `orderbook` alias, so the response shape is unchanged and no consumer of
SgOrder / SgTransaction had to move.

2. Dispair resolution assumes getters the RaindexV6 deployer does not have.

resolveVersionContracts derives the interpreter and store by calling
I_INTERPRETER() / I_STORE() on the configured deployer. The RaindexV6-era
deployer exposes only parse2, parsePragma1, describedByMetaV1,
buildIntegrityFunctionPointers and supportsInterface, so both reads revert,
contracts.v6 comes back undefined, and every order is skipped with "Cannot
trade as dispair addresses are not configured for order V4 trade" even though
dispair is configured.

`contracts.<version>.interpreter` and `.store` are now optional overrides. When
given they are used directly; otherwise the onchain reads happen exactly as
before, so existing configs are unaffected.

3. BASES_TO_CHECK_TRADES_AGAINST was indexed unguarded.

getCounterpartyOrdersAgainstBaseTokens throws a TypeError the first time it
enumerates intra-orderbook counterparties on any chain sushi has no routing
bases for. Guarded with `?? []`.

Also bumps the sushi submodule to the Robinhood Chain (4663) support branch.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HiqQdxokJ4edjAFyAkN9G3
@coderabbitai

coderabbitai Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: ce738815-bf80-4319-8245-9f3f6f491193

📥 Commits

Reviewing files that changed from the base of the PR and between d3241a0 and 61eaa19.

📒 Files selected for processing (13)
  • config.example.yaml
  • lib/sushiswap
  • src/config/validators.test.ts
  • src/config/validators.ts
  • src/config/yaml.test.ts
  • src/config/yaml.ts
  • src/order/index.test.ts
  • src/order/index.ts
  • src/state/contracts.test.ts
  • src/state/contracts.ts
  • src/subgraph/index.ts
  • src/subgraph/query.test.ts
  • src/subgraph/query.ts

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


Walkthrough

The change adds optional interpreter and store contract overrides, resolves missing addresses from chain data, adds v6-aware subgraph queries, handles missing base-token configuration, and updates the Sushiswap submodule.

Changes

Contract address overrides

Layer / File(s) Summary
Contract override configuration
src/config/yaml.ts, src/config/validators.ts, config.example.yaml, src/config/*.test.ts
Configuration, validation, examples, and tests now include optional interpreter and store addresses for v4, v5, and v6.
On-chain contract resolution
src/state/contracts.ts, src/state/contracts.test.ts
Configured addresses take precedence. Missing addresses still use version-specific on-chain reads.

Version-aware subgraph queries

Layer / File(s) Summary
Version-specific query generation
src/subgraph/query.ts, src/subgraph/query.test.ts
Query builders select legacy orderbook fields or v6 raindex fields and aliases.
Version-aware query integration
src/subgraph/index.ts
Orderbook, order, and event requests now pass the detected subgraph version.

Base-token filtering

Layer / File(s) Summary
Missing base-token configuration
src/order/index.ts, src/order/index.test.ts
Filtering uses an empty list when the current chain has no configured base tokens.

Sushiswap submodule update

Layer / File(s) Summary
Submodule pointer update
lib/sushiswap
The submodule pointer references a newer Sushiswap commit.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: rouzwelt

Sequence Diagram(s)

sequenceDiagram
  participant SubgraphIndex
  participant QueryBuilder
  participant SubgraphAPI
  SubgraphIndex->>QueryBuilder: provide detected subgraph version
  QueryBuilder->>QueryBuilder: build legacy or v6 GraphQL query
  SubgraphIndex->>SubgraphAPI: submit generated query
Loading

Merge Risk: ⚪ Minimal · up to 61eaa

No actionable merge-blocking risk remains in the reviewed changes.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 11 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the primary changes: v6 subgraph query support and resolution updates for RaindexV6. It is concise and related to the pull request objectives, although "dispair" appears t…
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 11 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 2026-09-11-robinhood-chain

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.

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