Remove BTC purchase mechanism on Scrypt#3743
Open
TaprootFreak wants to merge 2 commits into
Open
Conversation
Re-point Rule 313 (Scrypt/EUR redundancy) from Action 261 (Scrypt sell-if-deficit BTC) to Action 233 (Scrypt sell USDT), matching the existing CHF route (Rule 312). Remove the now unreferenced Action 261. Scrypt's BTC/EUR pricing is structurally worse than its USDT pairs (~0.6% spread vs ~0.13%). Incident on 2026-05-21 saw a 570k EUR buy_crypto routed to Scrypt BTC/EUR at +0.41% premium over Kraken VWAP because Rule 210 (Binance USDT refill) was Inactive. Routing EUR via USDT eliminates the costly BTC fill. Rule 314 (Scrypt/BTC withdraw) is retained as cleanup path for any residual BTC sitting on Scrypt. Closes #3739
Structurally remove the ability to acquire BTC via Scrypt. Scrypt's BTC/EUR spreads are materially worse than its USDT/EUR pairs (~0.6% vs ~0.13%). BTC acquisition must route through Binance USDT. - Drop the `sell-if-deficit` command from ScryptAdapter (enum entry, command registration, completion check, param validation, the `sellIfDeficit` method itself and its param helpers) - Drop now-unused constructor dependencies and imports (LiquidityManagementRuleRepository, LiquidityBalanceRepository, BuyCryptoService, PriceCurrency, forwardRef/Inject) - Add structural guards in `sell()` (tradeAsset === 'BTC') and `buy()` (targetAsset.dexName === 'BTC') that throw OrderNotProcessableException before any balance/price logic — no future LM rule misconfiguration can re-introduce BTC acquisition via Scrypt Relates to #3739
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
On 2026-05-21, buy_crypto #123090 routed a 570'000 EUR -> BTC trade onto Scrypt because Binance had insufficient BTC (Rule 192) and the Binance USDT refill pipeline (Rule 210) is
Inactive. We paid 66'487 EUR/BTC on Scrypt vs. Kraken VWAP @ 13:44 UTC of 66'218 EUR/BTC -- a +0.41% premium, ~2'257 EUR more than a hypothetical Kraken-VWAP fill.In our 6-month history Scrypt BTC/EUR averages a ~0.6% spread over reference, while Scrypt USDT/EUR is ~0.13%. We should not be buying BTC on Scrypt when a cheaper route exists.
The previous attempt (PR #3740) was DB-only -- a future LM rule misconfiguration could re-introduce the same incident. This PR enforces the policy structurally in code so it cannot happen again.
Closes #3739
What
Code (
src/subdomains/core/liquidity-management/adapters/actions/scrypt.adapter.ts)sell-if-deficitcommand fromScryptAdapter(enum entry, command registration, completion check, param validation, thesellIfDeficitmethod, and its param helpers)LiquidityManagementRuleRepository,LiquidityBalanceRepository,BuyCryptoService,PriceCurrency,forwardRef,Inject)sell()that throwsOrderNotProcessableExceptionwhentradeAsset === 'BTC'-- fails fast before any balance/price logicbuy()that throwsOrderNotProcessableExceptionwhentargetAssetEntity.dexName === 'BTC'-- same fail-fast semanticsThese guards make it impossible for any LM rule misconfiguration to acquire BTC via Scrypt.
Migration (
migration/1779381590531-RouteScryptEurViaUsdt.js)up(): re-point Rule 313 (Scrypt/EUR redundancy) from Action 261 to Action 233 (Scrypt sell USDT, same action already used by Rule 312 for CHF); then delete Action 261 (Scrypt sell-if-deficit BTC)down(): re-insert Action 261 with original params viaIDENTITY_INSERTand re-point Rule 313 back to 261Prerequisite (out of scope, blocks safe deploy)
Rule 210 (Binance/USDT) is
Inactiveas of 2026-05-21 -- this is exactly why the 2026-05-21 trade fell back to Scrypt in the first place. It must be re-activated before deploying this PR, otherwise large BTC buy_crypto orders will pile up onMissingLiquidityonce the Scrypt BTC path is cut. Verify with:Acceptance criteria
migration/with a timestamp >1775745823000(1779381590531)up()reroutes Rule 313 to Action 233 and deletes Action 261down()restores the previous statesell()andbuy()prevent BTC acquisition via Scryptsell-if-deficitcommand fully removed fromScryptAdapterdeveloponDFXswiss/apiVerification queries
Before merge
After deploy
End-to-end smoke test on DEV
liquidity_management_pipeline-- confirm new pipeline targets Rule 313 with action 233 (not 261)exchange_txshows aUSDT/EURScrypt trade, notBTC/EUR