Skip to content

fix(swapRebalancer): align Binance pre-deposit TTL with OFT bridge#3436

Merged
nicholaspai merged 2 commits into
masterfrom
droplet/T90K0AL22-C0AFB0BP3SB-1780080504-138269
May 29, 2026
Merged

fix(swapRebalancer): align Binance pre-deposit TTL with OFT bridge#3436
nicholaspai merged 2 commits into
masterfrom
droplet/T90K0AL22-C0AFB0BP3SB-1780080504-138269

Conversation

@droplet-rl
Copy link
Copy Markdown
Contributor

Summary

The BinanceStablecoinSwapAdapter created its PENDING_BRIDGE_PRE_DEPOSIT order with the default 1h Redis TTL even when the underlying bridge was a long-finality OFT route (USDT0 from HyperEVM, ~12h). The order was then silently pruned by BaseAdapter._redisCleanupPendingOrders while the bridge was still in flight, so the entire swap context (deposit-to-Binance, market order, withdraw-to-destination, "Order has finalized" Slack message) was lost.

OftAdapter already handles this for its own pending-order entry via a 24h ttlOverride in initializeRebalance. This PR extracts that decision into getOftPreDepositOrderTtlOverride and re-uses it in BinanceStablecoinSwapAdapter so both adapters keep the same TTL on the same underlying bridge.

Repro

For order 0xa7baaec4e0bdc6effd2c833033b057e1 (Slack: zbot-across-rebalancer-circle-hypercore) the swap-rebalancer logs in bots-across-3839 show:

  • +0m — order created, status PENDING_BRIDGE_PRE_DEPOSIT
  • +56m"Not enough USDT balance on Binance deposit network 42161 to progress the order ... with status PENDING_BRIDGE_TO_BINANCE_NETWORK" (the OFT bridge from HyperEVM hadn't landed yet)
  • +60mBaseAdapter._redisCleanupPendingOrders: "Deleting expired order details for cloid ... from status set binance-stablecoin-swap:pending-bridge-pre-deposit:..."

The OFT adapter's own entry kept the bridge tracked (24h TTL), but the Binance adapter's swap tag was lost when its entry was pruned, so the eventual Binance deposit was no longer recognized as belonging to a swap.

Changes

  • src/rebalancer/adapters/oftAdapter.ts — extract getOftPreDepositOrderTtlOverride(rebalanceRoute) and use it inside OftAdapter.initializeRebalance (no behavior change for OFT).
  • src/rebalancer/adapters/binance.ts — pass getOftPreDepositOrderTtlOverride(rebalanceRoute) to _redisCreateOrder on the pre-deposit-bridge path. Only USDT routes go through OFT today (_bridgeToChain switches on token); USDC goes through CCTP, which has short finality (≤~20m) and stays on the default 1h TTL.
  • src/rebalancer/README.md — short note on per-adapter TTL overrides and the fact that _redisUpdateOrderStatus does not refresh the TTL.

Notes / follow-ups

  • TTL is only set at order creation. _redisUpdateOrderStatus (baseAdapter.ts:153-170) does not refresh it, so the value set up front is the lifetime of the whole order across all status transitions. The 24h budget cleanly covers the ~12h OFT leg + Binance deposit + market order + Binance withdrawal.
  • Independent follow-up worth considering: make _redisCleanupPendingOrders emit a warn (or Slack alert) when it expires an order with PENDING_BRIDGE_* / PENDING_DEPOSIT / etc., so future silent drops become visible.
  • Operational mitigation if this happens again before this lands: set REBALANCER_PENDING_ORDER_TTL=86400 on the swap-rebalancer pod (overrides the default for all orders).

Test plan

  • yarn typecheck
  • yarn lint
  • yarn test test/PendingBridgeAdapters.ts test/BinanceAdapter.helpers.ts test/BinanceAdapter.conversions.ts
  • Reviewer to confirm whether a unit test for the new TTL override path should be added in test/PendingBridgeAdapters.ts or test/BinanceAdapter.*.ts — no existing test exercises _redisCreateOrder's TTL.
  • After deploy, verify the next HyperEVM USDT swap order survives past 1h in Redis and emits the "Order has finalized" Slack message.

🤖 Generated with Claude Code

The Binance swap adapter created its PENDING_BRIDGE_PRE_DEPOSIT order with
the default 1h Redis TTL even when the underlying bridge was a long-finality
OFT route (USDT0 from HyperEVM, ~12h). The order was then silently pruned by
BaseAdapter._redisCleanupPendingOrders while the bridge was still in flight,
so the swap context (deposit-to-Binance, market order, withdraw-to-destination,
"Order has finalized" Slack message) was lost.

Extract getOftPreDepositOrderTtlOverride from OftAdapter and reuse it in
BinanceStablecoinSwapAdapter so both adapters keep the same TTL on the same
underlying bridge.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@nicholaspai nicholaspai marked this pull request as ready for review May 29, 2026 20:25
@nicholaspai nicholaspai merged commit da67de9 into master May 29, 2026
5 checks passed
@nicholaspai nicholaspai deleted the droplet/T90K0AL22-C0AFB0BP3SB-1780080504-138269 branch May 29, 2026 20:33
@droplet-rl
Copy link
Copy Markdown
Contributor Author

Reviewed the approval — nicholaspai's review left no body text and no inline comments, and the PR has already been merged (da67de9b, 2026-05-29 20:33 UTC). Nothing to address.

For the record, the two open boxes from the PR description are still worth tracking:

  • Whether to add a unit test for the new TTL override path in test/PendingBridgeAdapters.ts or test/BinanceAdapter.*.ts (no existing test exercises _redisCreateOrder's TTL).
  • Post-deploy verification that the next HyperEVM USDT swap order survives past 1h in Redis and emits the "Order has finalized" Slack message.

Happy to follow up on either if you want.

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.

2 participants