Skip to content

[sdk/simplex/indexer]: off-chain support for cross-chain partial fills #982

Description

@seunlanlege

Summary

#980 adds cross-chain partial fills to IntentGatewayV2 at the contract level (multiple solvers each fill a slice of a cross-chain order; RedeemEscrowPartial releases a proportional escrow slice without finalizing; cancels refund only the proven-unredeemed fraction). That PR is contract-only — its own "Follow-ups" section defers the off-chain work. This issue tracks everything else required to ship the feature end-to-end.

Prerequisite: complete #981 first

This work should land after #981 (make IntentGatewayV2 a UUPS proxy upgradeable via cross-chain governance). Reasons:

  • Cross-chain partial fills are a substantial change to a fund-custody contract deployed at one canonical address across 9 chains. Without the proxy, rolling it out means redeploying and re-registering the gateway on every chain — which changes the canonical address and breaks cross-chain auth (_authenticate keys off the gateway address) and any in-flight orders. With the proxy, it ships as a single coordinated governance upgrade via the intents-coprocessor, preserving the address.
  • The PR itself flags "cross-chain fund movement — independent/cloud review recommended before mainnet." The proxy gives a governance-driven hotfix/rollback path if an issue is found post-deployment, instead of another multi-chain redeploy.
  • [evm]: cross-chain partial fills for IntentGatewayV2 #980 adds storage (_partialFills use for cross-chain, plus a slot guard). Landing the proxy first fixes the canonical storage layout so these additions are appended cleanly under the append-only rule.

Off-chain work required

SDK (sdk/packages/sdk/src/protocols/intents/)

  • Bid.ts / BidManager.ts — construct partial cross-chain fills (fill a slice of the outputs), decode/allow partial-amount fill-options for cross-chain bids. Today Bid.ts parses OrderFilled/PartialFill only to classify status; it must also be able to build a partial cross-chain fill.
  • OrderExecutor.ts — extend the cross-chain lifecycle (AWAITING_BIDS → BIDS_RECEIVED → BID_SELECTED → FILLED) to support repeated PARTIAL_FILL transitions like the same-chain path already does, until the order is fully filled, cancelled, or expired.
  • OrderStatusChecker.ts — cross-chain status can no longer be derived from the single _filled slot (it's cleared on partial, set only on completion). Read _partialFills per output to compute fill progress.
  • OrderCanceller.ts — cross-chain cancel quoting/refund must reflect that only the proven-unredeemed fraction is refunded (the GET proof now proves _partialFills), not the full escrow.
  • types.ts — add the RedeemEscrowPartial request kind and any new event shapes (EscrowReleased now fires per source-side release and carries the solver).

Simplex (sdk/packages/simplex/)

  • core/filler.ts + strategies/{base,basic,fx}.tscanFill/fill decisioning currently treats cross-chain as all-or-nothing. Add slice sizing for cross-chain orders and the ability to submit a partial fill.
  • Fee-pot economics — the completing solver takes the whole fee pot ("completing-solver-takes-all"). Strategy profitability/bid logic must account for this: a partial filler that never completes earns no fees, which changes expected value.
  • In-flight redeem risk — solvers must tolerate the cancel-vs-redeem race (cancel refunds only the unredeemed fraction; an in-flight RedeemEscrowPartial stays covered). Settlement tracking must not assume a fill is final until the finalizing RedeemEscrow.
  • core/event-monitor.ts — already watches OrderFilled/PartialFill; confirm cross-chain partials are surfaced and re-evaluated for follow-on fills.

Indexer (sdk/packages/indexer/src/handlers/events/intentGatewayV3/ + services/intentGatewayV3.service.ts)

  • ABI regenIntentGatewayV2Abi needs regenerating for changed event signatures (e.g. EscrowReleased now carries the solver and fires on every source-side release including partial redeems).
  • escrowReleasedV3 handler — must aggregate cumulative released amount per commitment (and per solver) rather than treating a release as terminal; partial redeems are now non-finalizing.
  • partialFilledV3 / orderFilledV3 handlers — represent "cross-chain order partially redeemed, escrow still open" in the order/settlement model; finalization only on the completing RedeemEscrow.
  • escrowRefundedV3 handler — handle partial refund amounts from cross-chain cancels (unredeemed fraction), not just full refunds.

Coprocessor (modules/pallets/intents-coprocessor/) — secondary

Acceptance criteria

  • [evm/runtime]: make IntentGatewayV2 upgradeable via cross-chain governance #981 merged and IntentGatewayV2 deployed as a proxy; this feature ships as a governance upgrade.
  • SDK can construct, track, and cancel partial cross-chain orders end-to-end.
  • Simplex can size, submit, and settle partial cross-chain fills with fee-pot-aware profitability.
  • Indexer correctly tracks cumulative cross-chain releases, partial-redeem state, and partial refunds; ABI regenerated.
  • Coprocessor RequestKind byte parity maintained with the contract.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions