Skip to content

[ANCHOR-1226]: SEP-6 deposit/withdraw-exchange skips the quote buy-asset check SEP-24 enforces, binding a quote to a mismatched destination asset#1969

Merged
amandagonsalves merged 3 commits into
developfrom
fix/anchor-1226
Jul 10, 2026
Merged

[ANCHOR-1226]: SEP-6 deposit/withdraw-exchange skips the quote buy-asset check SEP-24 enforces, binding a quote to a mismatched destination asset#1969
amandagonsalves merged 3 commits into
developfrom
fix/anchor-1226

Conversation

@amandagonsalves

@amandagonsalves amandagonsalves commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Description

SEP-6 deposit-exchange/withdraw-exchange never checked that a SEP-38 quote's buy asset matched the request's destination_asset. ExchangeAmountsCalculator.calculateFromQuote — the only entry point SEP-6 uses — hardcoded the buy-asset argument to null when calling validateQuoteAgainstRequestInfo, skipping the buy-asset-mismatch check that method already implements (and that SEP-24 already relies on via a different entry point). A user could bind a quote priced for a cheap asset to a transaction recorded against a different, valuable destination_asset, causing the operator to lose the difference at settlement.

Changes

  • ExchangeAmountsCalculator.calculateFromQuote: signature changed to accept buyAsset, forwarded into validateQuoteAgainstRequestInfo instead of null. No new overload — the 3-arg version was unconditionally unsafe and had exactly two callers, both already fixed below.
  • Sep6Service.depositExchange/withdrawExchange: both now pass their already-resolved destination/buy asset into the call.
  • ExchangeAmountsCalculatorTest: updated all 8 existing calls for the new signature; added tests proving the fixed method rejects a mismatched buy asset and accepts a matching one.
  • Sep6ServiceTest: updated all 8 mock stubs for the new arity; added two tests (deposit-exchange, withdraw-exchange) capturing the calculateFromQuote call and asserting the resolved destination asset is what's actually passed as buyAsset.

Acceptance Criteria

  • deposit-exchange/withdraw-exchange reject a quote whose buy asset doesn't match destination_asset.
  • A quote whose buy asset matches destination_asset succeeds unchanged.
  • No other caller of calculateFromQuote exists or broke (only the two Sep6Service call sites in production code).

Context

#3815607

Testing

  • Unit: ./gradlew :core:test --tests "org.stellar.anchor.util.ExchangeAmountsCalculatorTest"
  • Unit: ./gradlew :core:test --tests "org.stellar.anchor.sep6.Sep6ServiceTest"
  • Full suite: ./gradlew :core:build

Documentation

N/A

Known limitations

None.

* update calculatefromquote method signature to include buy asset for validation

* update sep6service to pass buy asset to quote calculation

* add tests for buy asset validation in quote calculation
@amandagonsalves amandagonsalves self-assigned this Jul 7, 2026
Copilot AI review requested due to automatic review settings July 7, 2026 17:03

Copilot AI 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.

Pull request overview

This pull request closes a validation gap in SEP-6 deposit/withdraw-exchange flows by ensuring a provided SEP-38 quote is validated against the destination (buy) asset, aligning SEP-6 behavior with SEP-24 and preventing quotes from being bound to mismatched destination assets.

Changes:

  • Updated ExchangeAmountsCalculator.calculateFromQuote(...) to accept a buyAsset and validate it against the quote’s buy_asset.
  • Updated SEP-6 deposit-exchange and withdraw-exchange services to pass the resolved destination asset as buyAsset.
  • Expanded/updated unit tests to cover mismatched vs matching buy-asset behavior and verify SEP-6 passes the correct buy asset.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
core/src/main/java/org/stellar/anchor/util/ExchangeAmountsCalculator.java Adds buyAsset parameter to calculateFromQuote and validates it against the quote’s buy asset.
core/src/main/java/org/stellar/anchor/sep6/Sep6Service.java Passes resolved destination asset into quote-based amount calculation for deposit/withdraw exchange.
core/src/test/kotlin/org/stellar/anchor/util/ExchangeAmountsCalculatorTest.kt Updates call sites for new signature and adds tests for buy-asset mismatch/match behavior.
core/src/test/kotlin/org/stellar/anchor/sep6/Sep6ServiceTest.kt Updates mocks for new signature and adds tests asserting SEP-6 passes the correct buy asset.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 28 to 31
* @param quoteId The quote ID
* @param sellAsset The asset the user is selling
* @param buyAsset The asset the user is buying (the request's destination asset)
* @param sellAmount The amount the user is selling
@amandagonsalves
amandagonsalves merged commit c1ed5a3 into develop Jul 10, 2026
14 of 16 checks passed
@amandagonsalves
amandagonsalves deleted the fix/anchor-1226 branch July 10, 2026 19:33
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.

3 participants