Skip to content

Add Bitget buy-order support via reverse-quote endpoint - #4378

Merged
squadgazzz merged 15 commits into
mainfrom
feat/bitget-buy-orders
May 5, 2026
Merged

squadgazzz merged 15 commits into
mainfrom
feat/bitget-buy-orders

Conversation

@squadgazzz

Copy link
Copy Markdown
Contributor

Description

Bitget's /swapr endpoint supports buy quotes (requestMode = "minAmountOut") by running a recursion server-side on top of sell quotes. Wiring this up unlocks Bitget as a native-price source for the long tail of tokens that other estimators cover poorly. Today the integration only supports sell orders.

The reverse-quote on real auction buy orders is correct end-to-end (positive overshoot accrues to the settlement buffer, the user receives exactly their signed buy amount, GPv2Settlement does no expected-vs-actual interaction-output check), but it can cost the user up to the configured slippage in surplus, so it's gated behind a config flag and off by default.

Changes

  • New Side::Buy code path in the Bitget integration, calling /bgw-pro/swapx/pro/swapr with requestMode = "minAmountOut"
  • Caps the reported swap output to order.buy.amount so CoW exact-out fulfillment passes
  • New enable-buy-orders config flag, off by default, gating the buy path
  • decimal_to_wei now rounds to the token's precision (Bitget can return more decimal digits than the token has)
  • Rate-limit pause between iterations in the live multi-chain test

How to test

Existing tests plus new mock + ignored live tests. Run the live one with credentials:

BITGET_API_KEY=... BITGET_API_SECRET=... \
  cargo nextest run -p solvers --run-ignored only swap_buy_all_chains

squadgazzz added 3 commits May 4, 2026 08:48
Routes Side::Buy orders to /bgw-pro/swapx/pro/swapr with
requestMode=minAmountOut. Bitget runs the recursion server-side, so we
just translate the response into a dex::Swap. Output is capped to
order.amount.get() to satisfy CoW exact-out fulfillment, any on-chain
overshoot accrues to the settlement buffer as positive surplus.

Unlocks Bitget as a native-price source for niche tokens, where the
autopilot probes prices via OrderKind::Buy with a fixed native amount.
Off by default. When disabled, Side::Buy short-circuits to
OrderNotSupported without touching the API. Enabled, buy orders go
through the existing reverse-quote path.

The reverse-quote path costs the user up to `slippage` of surplus on
real auctions (overshoot accrues to the settlement buffer rather than
the user), so we want a per-deployment switch before turning it on.
@squadgazzz
squadgazzz requested a review from a team as a code owner May 4, 2026 09:57
@squadgazzz
squadgazzz marked this pull request as draft May 4, 2026 10:01

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for buy orders in the Bitget solver by integrating their reverse-quote API endpoint (/swapr). It includes new data transfer objects for reverse-swap requests and responses, configuration options to enable or disable buy orders, and updated logic in the Bitget struct to handle both sell and buy order paths. My feedback focuses on two critical issues: the current decimal-to-wei conversion uses default rounding which is unsafe for financial settlements, and the buy order handler only processes the first transaction from the API response, potentially ignoring necessary multi-hop steps or setup calls.

Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
@squadgazzz
squadgazzz marked this pull request as ready for review May 4, 2026 12:48

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for buy orders in the Bitget DEX solver by implementing the reverse-quote endpoint. Key changes include the addition of an enable_buy_orders configuration flag, new DTOs for reverse-swap requests, and specialized rounding logic for decimal-to-wei conversions to maintain settlement integrity. Feedback focused on a logic improvement for the sanity check of expected output amounts, suggesting that rounding down is safer to ensure consistency with on-chain enforcement.

Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request implements buy order support for the Bitget DEX solver using the reverse-quote endpoint. The implementation includes new configuration settings, DTOs for reverse swaps, and a rounding-aware decimal-to-wei conversion utility. The review feedback identifies a logic error in the sanity check for expected output, recommending a change from rounding up to rounding down to prevent the acceptance of trades that could revert due to insufficient output.

Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request implements buy order support for the Bitget DEX by integrating the reverse-quote API endpoint. The changes include a new configuration flag, DTOs for reverse-swap requests, and a rounding utility for converting API decimal responses to wei. Feedback was provided regarding the sanity check for expected output, suggesting the use of downward rounding to ensure the received amount strictly satisfies the order requirements and avoids on-chain reverts.

Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
Comment thread crates/solvers/src/infra/config/dex/bitget/file.rs Outdated
Comment thread crates/solvers/src/infra/dex/bitget/dto.rs Outdated
Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
Comment thread crates/solvers/src/tests/bitget/api_calls.rs Outdated
Comment thread crates/solvers/src/tests/bitget/api_calls.rs Outdated
Comment thread crates/solvers/src/tests/bitget/api_calls.rs
Comment on lines +294 to +299
// Compare the raw BigDecimals so the check doesn't depend on
// rounding direction.
let requested_out = wei_to_decimal(order.amount.get(), buy_decimals);
if response.expected_amount_out < requested_out {
return Err(Error::NotFound);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It's less than because "more than" (as stated in the docs) reverts to the buffer, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Exactly. expected_amount_out > requested_out is the normal case (Bitget plans to deliver more than asked, the overshoot lands in the buffer). < requested_out means Bitget itself thinks it'll undershoot, in which case the on-chain minAmountOut check would revert. So we bail on the strict-less-than path and let the strict-greater-or-equal path through.

@MartinquaXD MartinquaXD left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Change and tests look good to me. Only nits.

Comment thread crates/solvers/src/infra/dex/bitget/dto.rs Outdated
Comment thread crates/solvers/src/infra/dex/bitget/mod.rs Outdated
Comment thread crates/solvers/src/tests/bitget/api_calls.rs Outdated
@squadgazzz
squadgazzz enabled auto-merge May 5, 2026 11:10
@squadgazzz
squadgazzz added this pull request to the merge queue May 5, 2026
Merged via the queue into main with commit 821ca33 May 5, 2026
20 checks passed
@squadgazzz
squadgazzz deleted the feat/bitget-buy-orders branch May 5, 2026 11:28
@github-actions github-actions Bot locked and limited conversation to collaborators May 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants