Skip to content

feat(flowstate): add FlowState C1 pools as a liquidity source - #1208

Open
danielthefoe wants to merge 2 commits into
VeloraDEX:masterfrom
danielthefoe:feat/flowstate-dex
Open

feat(flowstate): add FlowState C1 pools as a liquidity source#1208
danielthefoe wants to merge 2 commits into
VeloraDEX:masterfrom
danielthefoe:feat/flowstate-dex

Conversation

@danielthefoe

@danielthefoe danielthefoe commented Jul 16, 2026

Copy link
Copy Markdown

PR title

feat: add FlowState (C1 pools) as a liquidity source

PR description

FlowState - C1 pools as a liquidity source

Adds FlowState as a V6 DEX integration. FlowState runs on-chain "C1 pools"
that let buyers spend native ETH to buy an ERC-20 out of a pool at the
on-chain 1inch spot price. This PR lets Velora route ETH→token buys into them.

How it works

  • Direction: exact-input SELL, native ETH → ERC-20 only. Every other
    case (BUY, non-ETH src, ETH dest, token→token) returns []/null, so the
    integration is strictly additive - it can only contribute a new source on
    the one shape it serves, never alter or break an existing route.
  • Pricing: fills at the 1inch spot oracle (getRateToEth) - the exact rate
    the pool's on-chain checkAmounts uses - flat/zero-slippage, capped by the
    pool's live token balance. getPricesVolume reads rate + balances via
    tryAggregate, so an unpriceable token (oracle revert) or a broken
    balanceOf degrades to "no quote" instead of disrupting the pricing batch.
  • Execution: getDexParam encodes buyFromPool(pool, amount, resellerCode, recipient) (payable). The token amount is re-derived from srcAmount at
    the quoted rate so it lands centered in the contract's ±1% checkAmounts
    band. Native ETH is consumed directly (needWrapNative: false,
    dexFuncHasRecipient: true, Flag 9 - no insertFromAmount).
  • Discovery: active pools per token/chain from FlowState's indexer (Hasura).

Chains

Ethereum, BSC, Base, Arbitrum. The 1inch oracle (0x…6786) and the
CREATE2 router (0x93B7C8…) are identical across all four (verified against the
contract's own PriceOracleAddresses).

Tests

  • Unit (deterministic, offline): additivity guards + buyFromPool calldata
    encoding + V6 flags.
  • Integration (live, no Tenderly): discovers a live pool and asserts the
    module's multicall pricing is byte-identical to an independent on-chain
    recompute of the contract formula, capped by inventory.
    Run: npx jest src/dex/flowstate

Known limitation (documented in getDexParam)

The pool takes native ETH via msg.value + a static token amount. As a
non-first hop consuming intermediate native ETH, msg.value is the prior
hop's runtime output and can drift >1% from the quote, tripping checkAmounts
and reverting that route only - fail-closed (no fund loss, no effect on
other DEXes). The single-hop ETH-buy path (the primary use case) is unaffected.
getPricesVolume declines when isFirstSwap === false.

Open question for maintainers: does the production pricing engine pass
isFirstSwap to getPricesVolume? The open-source pricing-helper passes 7
args (no isFirstSwap); if production passes it, the guard fully prevents the
non-first-hop case. If not, is there a preferred way for a payable/fixed-amount
source to opt out of intermediate placement? The clean long-term fix is
contract-side (a buyFromPool variant that derives the token amount from
msg.value on-chain, making any msg.value safe).

Notes

  • Pure dex-lib integration.
  • -e2e.test.ts not included: it simulates swaps via a fork/Tenderly, which we
    validated manually instead. Happy to add it in-repo if you'd prefer.

Note

Medium Risk
New routing path for native-ETH swaps with payable execution and contract ±1% amount checks; mis-pricing or multi-hop placement could cause route reverts, though guards and fail-closed behavior limit blast radius.

Overview
Adds a new FlowState V6 DEX that routes native ETH → ERC-20 exact-input buys through on-chain C1 pools via payable buyFromPool, and registers it on Ethereum, BSC, Base, and Arbitrum.

Discovery & pricing: Active pools come from FlowState’s Hasura GraphQL indexer (short TTL cache, stale snapshot on errors). Quotes use the on-chain 1inch getRateToEth rate plus live pool balanceOf, with tryAggregate so oracle/token failures drop to “no quote” instead of breaking the batch. Output is flat at the oracle rate and capped at inventory (over-size amounts price to 0).

Additive routing: Every path except SELL with native ETH source and ERC-20 dest returns []/null; getPricesVolume also returns null when isFirstSwap === false so the source is not used as a middle hop where static calldata vs runtime msg.value could revert.

Execution: getDexParam encodes buyFromPool with token amount recomputed from srcAmount and the quoted rate (not min-out), native ETH (Flag 9, no insertFromAmount), and tokens sent to the route recipient.

Unit tests lock additivity guards and calldata/flags; a live integration test checks discovery, pricing vs an independent on-chain formula, and getTopPoolsForToken.

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

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want higher recall? High effort reviews run extra passes and find more bugs. A team admin can switch effort levels in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ac85b3c. Configure here.

Comment thread src/dex/flowstate/flowstate.ts
Comment thread src/dex/flowstate/flowstate.test.ts
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