Skip to content

Stop reporting a false below-limit error for CACAO - #520

Open
j0ntz wants to merge 2 commits into
masterfrom
jon/fix-cacao-below-min-error
Open

j0ntz wants to merge 2 commits into
masterfrom
jon/fix-cacao-below-min-error

Conversation

@j0ntz

@j0ntz j0ntz commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Asana task

A CACAO to BTC swap of 5,000 USD showed "Amount is below the min limit" with no minimum. Maya Protocol is the only provider for CACAO pairs, and Maya had BTC trading halted when this was tested on 2026-11-02 (HALTBTCTRADING, HALTSIGNINGBTC). No quote exists at any amount during a halt.

The device log showed two provider errors on the from side:

  • Maya: a generic Could not get quote, because Mayanode returned its error as HTTP 200 and getQuote only read errors from an error status.
  • Rango: SwapBelowLimitError with an empty minimum. Rango answers NO_ROUTE at every amount, and the plugin treated a failed minimum search as below-limit.

Core ranks below-limit above every error except insufficient and pending funds. Rango's false error reached the user.

Rango (src/swap/defi/rango.ts)

Case Was Now
No amount has a route SwapBelowLimitError SwapCurrencyError
A higher amount has a route SwapBelowLimitError with that minimum Same
Only a smaller amount has a route SwapBelowLimitError Generic Rango error
Rango blames the amount (INPUT_LIMIT_ISSUE, "too low") SwapBelowLimitError Same
No rate, the search cannot run SwapBelowLimitError Generic Rango error

Thorchain and Maya (src/swap/defi/thorchain/thorchainCommon.ts)

getQuote reads the error from an HTTP 200 body as well as from an error status. Without this, the Rango change would turn a real too-small Maya swap into "No enabled exchanges support". zero emit asset counts as too small, and MAX_MIN_AMOUNT_PROBES caps the 10x retries because this path is now live on Maya. Other Mayanode errors, including a halt, stay generic.

Testing

Tested on the iOS simulator with the fixed plugin bundle on the agent role account. The frames are in the evidence table.

Scenario Result
Published 2.60.0, CACAO to BTC, 1 USD The reported below-limit card
Fixed, CACAO to BTC, 1 USD "No enabled exchanges support CACAO to BTC."
Fixed, CACAO to Arbitrum ETH, 0.03 USD Below-limit card kept, no funds moved
Fixed, CACAO to Arbitrum ETH, 0.53 USD Swap executed through Maya Protocol to the success scene
Fixed, plugins called directly, 43,156 CACAO (about 5,000 USD) to BTC Maya generic error, Rango SwapCurrencyError

Gaps

  • The 5,000 USD amount was not entered in the app: the test account holds about 1.30 USD of CACAO and the scene rejects amounts over balance. Rango's no-route reply does not depend on the amount, and the direct plugin call covers 5,000 USD.
  • A successful CACAO to BTC quote cannot be shown while Maya has BTC halted. This PR verifies the task's other expected result, a correct reason when no provider supports the pair.
  • The message says no exchange supports the pair and does not say the halt is temporary. Core has no error type for a temporary halt, and adding one is a separate change.

Test evidence

edebcd1
Stop calling Rango no-route a below-limit error
2026-11-02

1. before fix wrong below limit

2. after fix no enabled exchanges

3. after fix genuine below limit

4. after fix cacao arb quote

5. after fix cacao arb success

j0ntz added 2 commits November 2, 2026 12:06
Mayanode reports a failed quote as HTTP 200 with an error field, while
Thornode uses an HTTP error status. getQuote only looked for its too-small
errors on the error status, so a real too-small Maya swap surfaced as a
generic error instead of below-limit.

Read the error from either shape, count zero emit asset as too small, and
bound the 10x retries now that this path is live on Maya.
Rango answers NO_ROUTE when a pair has no route at any amount, such as when
a chain is halted. The plugin treated a failed minimum search as below-limit,
and core ranks that above every other provider's error, so a 43,156 CACAO to
BTC swap showed a minimum error with no minimum.

An empty search now throws SwapCurrencyError. A found minimum only counts when
it is above the request, and Rango's own amount complaints stay below-limit.
Without a rate the search never runs, so that case stays generic.
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