33 assert ,
44 BigNumber ,
55 BINANCE_NETWORKS ,
6+ BINANCE_WITHDRAWAL_STATUS ,
67 BinanceTransactionType ,
78 BinanceWithdrawal ,
89 bnZero ,
@@ -33,6 +34,7 @@ import { AugmentedTransaction } from "../../clients";
3334import { RebalancerConfig } from "../RebalancerConfig" ;
3435import { CctpAdapter } from "./cctpAdapter" ;
3536import { OftAdapter } from "./oftAdapter" ;
37+
3638interface SPOT_MARKET_META {
3739 symbol : string ;
3840 baseAssetName : string ;
@@ -43,6 +45,29 @@ interface SPOT_MARKET_META {
4345 isBuy : boolean ;
4446}
4547
48+ export function isFailedBinanceWithdrawal ( status ?: number ) : boolean {
49+ switch ( status ) {
50+ case BINANCE_WITHDRAWAL_STATUS . CANCELLED :
51+ case BINANCE_WITHDRAWAL_STATUS . REJECTED :
52+ case BINANCE_WITHDRAWAL_STATUS . FAILURE :
53+ return true ;
54+ default :
55+ return false ;
56+ }
57+ }
58+
59+ export function isTerminalBinanceWithdrawal ( status ?: number ) : boolean {
60+ switch ( status ) {
61+ case BINANCE_WITHDRAWAL_STATUS . CANCELLED :
62+ case BINANCE_WITHDRAWAL_STATUS . REJECTED :
63+ case BINANCE_WITHDRAWAL_STATUS . FAILURE :
64+ case BINANCE_WITHDRAWAL_STATUS . COMPLETED :
65+ return true ;
66+ default :
67+ return false ;
68+ }
69+ }
70+
4671export class BinanceStablecoinSwapAdapter extends BaseAdapter {
4772 private binanceApiClient : Binance ;
4873
@@ -307,12 +332,25 @@ export class BinanceStablecoinSwapAdapter extends BaseAdapter {
307332 continue ;
308333 } // Only proceed to update the order status if it has finalized:
309334 // @todo : Can we cache this result to avoid making the same query for orders with the same destination token and withdrawal network?
310- const { unfinalizedWithdrawals, finalizedWithdrawals } = await this . _getBinanceWithdrawals (
335+ const { unfinalizedWithdrawals, finalizedWithdrawals, failedWithdrawals } = await this . _getBinanceWithdrawals (
311336 orderDetails . destinationToken ,
312337 binanceWithdrawalNetwork ,
313338 Math . floor ( matchingFill . time / 1000 ) - 5 * 60 // Floor this so we can grab the initiated withdrawal data whose
314339 // ID we've already saved into Redis
315340 ) ;
341+ const failedWithdrawal = failedWithdrawals . find ( ( withdrawal ) => withdrawal . id === initiatedWithdrawalId ) ;
342+ if ( failedWithdrawal ) {
343+ this . logger . warn ( {
344+ at : "BinanceStablecoinSwapAdapter.updateRebalanceStatuses" ,
345+ message : `Withdrawal for order ${ cloid } failed on Binance, resetting it to retry withdrawal` ,
346+ cloid,
347+ initiatedWithdrawalId,
348+ failedWithdrawal,
349+ } ) ;
350+ await this . _redisDeleteInitiatedWithdrawalId ( cloid ) ;
351+ await this . _redisUpdateOrderStatus ( cloid , STATUS . PENDING_WITHDRAWAL , STATUS . PENDING_SWAP ) ;
352+ continue ;
353+ }
316354 const initiatedWithdrawalIsUnfinalized = unfinalizedWithdrawals . find (
317355 ( withdrawal ) => withdrawal . id === initiatedWithdrawalId
318356 ) ;
@@ -976,16 +1014,19 @@ export class BinanceStablecoinSwapAdapter extends BaseAdapter {
9761014 withdrawal . coin === token &&
9771015 withdrawal . network === BINANCE_NETWORKS [ chain ] &&
9781016 withdrawal . recipient === this . baseSignerAddress . toNative ( ) &&
979- withdrawal . status > 4
980- // @dev (0: Email Sent, 1: Cancelled 2: Awaiting Approval, 3: Rejected, 4: Processing, 5: Failure, 6: Completed)
1017+ isTerminalBinanceWithdrawal ( withdrawal . status )
9811018 ) ;
9821019 }
9831020
9841021 private async _getBinanceWithdrawals (
9851022 destinationToken : string ,
9861023 destinationChain : number ,
9871024 startTimeSeconds : number
988- ) : Promise < { unfinalizedWithdrawals : BinanceWithdrawal [ ] ; finalizedWithdrawals : BinanceWithdrawal [ ] } > {
1025+ ) : Promise < {
1026+ unfinalizedWithdrawals : BinanceWithdrawal [ ] ;
1027+ finalizedWithdrawals : BinanceWithdrawal [ ] ;
1028+ failedWithdrawals : BinanceWithdrawal [ ] ;
1029+ } > {
9891030 assert ( isDefined ( BINANCE_NETWORKS [ destinationChain ] ) , "Destination chain should be a Binance network" ) ;
9901031 const provider = await getProvider ( destinationChain ) ;
9911032 // @dev Binance withdrawals are fast, so setting a lookback of 6 hours should capture any unfinalized withdrawals.
@@ -1013,7 +1054,12 @@ export class BinanceStablecoinSwapAdapter extends BaseAdapter {
10131054
10141055 const finalizedWithdrawals : BinanceWithdrawal [ ] = [ ] ;
10151056 const unfinalizedWithdrawals : BinanceWithdrawal [ ] = [ ] ;
1057+ const failedWithdrawals : BinanceWithdrawal [ ] = [ ] ;
10161058 for ( const initiated of initiatedWithdrawals ) {
1059+ if ( isFailedBinanceWithdrawal ( initiated . status ) ) {
1060+ failedWithdrawals . push ( initiated ) ;
1061+ continue ;
1062+ }
10171063 const withdrawalAmount = toBNWei (
10181064 initiated . amount , // @dev This should be the post-withdrawal fee amount so it should match perfectly
10191065 // with the finalized amount.
@@ -1030,7 +1076,7 @@ export class BinanceStablecoinSwapAdapter extends BaseAdapter {
10301076 unfinalizedWithdrawals . push ( initiated ) ;
10311077 }
10321078 }
1033- return { unfinalizedWithdrawals, finalizedWithdrawals } ;
1079+ return { unfinalizedWithdrawals, finalizedWithdrawals, failedWithdrawals } ;
10341080 }
10351081
10361082 private _redisGetInitiatedWithdrawalKey ( cloid : string ) : string {
@@ -1043,6 +1089,11 @@ export class BinanceStablecoinSwapAdapter extends BaseAdapter {
10431089 return initiatedWithdrawal ;
10441090 }
10451091
1092+ private async _redisDeleteInitiatedWithdrawalId ( cloid : string ) : Promise < void > {
1093+ const initiatedWithdrawalKey = this . _redisGetInitiatedWithdrawalKey ( cloid ) ;
1094+ await this . redisCache . del ( initiatedWithdrawalKey ) ;
1095+ }
1096+
10461097 protected async _bridgeToChain (
10471098 token : string ,
10481099 originChain : number ,
0 commit comments