88 convertToNativeUnits ,
99 convertTo18Decimals ,
1010 safeParseBigInt ,
11+ getTonAssetDecimals ,
1112} from '../helpers' ;
1213import { jsonifyMap , jsonifyError } from '@mark/logger' ;
1314import {
@@ -182,7 +183,8 @@ async function getTonNativeBalance(
182183 }
183184
184185 return safeParseBigInt ( data . balance . toString ( ) ) ;
185- } catch {
186+ } catch ( error ) {
187+ console . log ( 'getTonNativeBalance error' , error ) ;
186188 return 0n ;
187189 }
188190}
@@ -352,7 +354,6 @@ interface RebalanceRunState {
352354export async function rebalanceTacUsdt ( context : ProcessingContext ) : Promise < RebalanceAction [ ] > {
353355 const { logger, requestId, config, rebalance, prometheus } = context ;
354356 const actions : RebalanceAction [ ] = [ ] ;
355-
356357 // Always check destination callbacks to ensure operations complete
357358 await executeTacCallbacks ( context ) ;
358359
@@ -1932,6 +1933,7 @@ const executeTacCallbacks = async (context: ProcessingContext): Promise<void> =>
19321933 } ) ;
19331934 continue ;
19341935 }
1936+ const tonUSDTDecimals = getTonAssetDecimals ( operation . tickerHash , config ) ?? 6 ;
19351937
19361938 // Check TON native balance for gas
19371939 const tonNativeBalance = await getTonNativeBalance ( tonWalletAddress , tonApiKey ) ;
@@ -1948,6 +1950,14 @@ const executeTacCallbacks = async (context: ProcessingContext): Promise<void> =>
19481950
19491951 // Get actual USDT balance on TON
19501952 const actualUsdtBalance = await getTonJettonBalance ( tonWalletAddress , jettonAddress , tonApiKey ) ;
1953+ const actualUsdtBalance18 = convertTo18Decimals ( actualUsdtBalance , tonUSDTDecimals ) ;
1954+ logger . info ( 'Ton Jetton Balance' , {
1955+ tonWalletAddress,
1956+ jettonAddress,
1957+ decimals : 6 ,
1958+ actualUsdtBalance : actualUsdtBalance . toString ( ) ,
1959+ actualUsdtBalance18 : actualUsdtBalance18 . toString ( ) ,
1960+ } ) ;
19511961
19521962 // CRITICAL: Use operation-specific amount, NOT the full wallet balance
19531963 // This prevents mixing funds from multiple concurrent flows
@@ -1967,22 +1977,22 @@ const executeTacCallbacks = async (context: ProcessingContext): Promise<void> =>
19671977 const minExpectedAmount = calculateMinExpectedAmount ( expectedAmount , slippageBps ) ;
19681978
19691979 // Validate: TON wallet must have at least the minimum expected amount
1970- if ( actualUsdtBalance < minExpectedAmount ) {
1980+ if ( actualUsdtBalance18 < minExpectedAmount ) {
19711981 // Not enough funds yet - Stargate might still be in transit or another flow took funds
19721982 logger . warn ( 'Insufficient USDT on TON for this operation - waiting for Stargate delivery' , {
19731983 ...logContext ,
19741984 expectedAmount : expectedAmount . toString ( ) ,
19751985 minExpectedAmount : minExpectedAmount . toString ( ) ,
1976- actualUsdtBalance : actualUsdtBalance . toString ( ) ,
1977- shortfall : ( minExpectedAmount - actualUsdtBalance ) . toString ( ) ,
1986+ actualUsdtBalance18 : actualUsdtBalance18 . toString ( ) ,
1987+ shortfall : ( minExpectedAmount - actualUsdtBalance18 ) . toString ( ) ,
19781988 note : 'Will retry when funds arrive. If persists, check Stargate bridge status.' ,
19791989 } ) ;
19801990 continue ;
19811991 }
19821992
19831993 // Calculate amount to bridge: min(expectedAmount, actualBalance)
19841994 // NEVER bridge more than the operation's expected amount
1985- const amountToBridgeBigInt = actualUsdtBalance < expectedAmount ? actualUsdtBalance : expectedAmount ;
1995+ const amountToBridgeBigInt = actualUsdtBalance18 < expectedAmount ? actualUsdtBalance18 : expectedAmount ;
19861996 const amountToBridge = amountToBridgeBigInt . toString ( ) ;
19871997
19881998 // Log if we're bridging less than expected (Stargate took fees)
@@ -1993,18 +2003,19 @@ const executeTacCallbacks = async (context: ProcessingContext): Promise<void> =>
19932003 recipient,
19942004 expectedAmount : expectedAmount . toString ( ) ,
19952005 minExpectedAmount : minExpectedAmount . toString ( ) ,
1996- actualUsdtBalance : actualUsdtBalance . toString ( ) ,
2006+ actualUsdtBalance18 : actualUsdtBalance18 . toString ( ) ,
19972007 amountToBridge,
19982008 stargateFeesDeducted : tookFees ,
19992009 note : tookFees
20002010 ? `Bridging ${ amountToBridge } (Stargate took ${ expectedAmount - amountToBridgeBigInt } in fees)`
20012011 : 'Bridging expected amount' ,
20022012 } ) ;
20032013
2014+ const amountToBridgeNative = convertToNativeUnits ( amountToBridgeBigInt , tonUSDTDecimals ) . toString ( ) ;
20042015 const transactionLinker = await tacInnerAdapter . executeTacBridge (
20052016 tonMnemonic ,
20062017 recipient ,
2007- amountToBridge ,
2018+ amountToBridgeNative ,
20082019 jettonAddress , // CRITICAL: Pass the TON jetton address for the asset to bridge
20092020 ) ;
20102021
@@ -2030,7 +2041,7 @@ const executeTacCallbacks = async (context: ProcessingContext): Promise<void> =>
20302041 originChainId : Number ( TON_LZ_CHAIN_ID ) ,
20312042 destinationChainId : Number ( TAC_CHAIN_ID ) ,
20322043 tickerHash : operation . tickerHash ,
2033- amount : amountToBridge , // Use actual amount, not original
2044+ amount : amountToBridgeBigInt . toString ( ) , // 18 decimals
20342045 slippage : 100 ,
20352046 // Use AWAITING_CALLBACK if we have transactionLinker (bridge submitted, awaiting completion)
20362047 // Use PENDING if no transactionLinker (bridge failed to submit, will retry)
@@ -2134,10 +2145,12 @@ const executeTacCallbacks = async (context: ProcessingContext): Promise<void> =>
21342145 } ) ;
21352146 continue ;
21362147 }
2148+ const tonUSDTDecimals = getTonAssetDecimals ( operation . tickerHash , config ) ?? 6 ;
21372149
21382150 if ( tonMnemonic && tonWalletAddress ) {
21392151 // Get actual USDT balance on TON
21402152 const actualUsdtBalance = await getTonJettonBalance ( tonWalletAddress , jettonAddress , tonApiKey ) ;
2153+ const actualUsdtBalance18 = convertTo18Decimals ( actualUsdtBalance , tonUSDTDecimals ) ;
21412154
21422155 if ( actualUsdtBalance === 0n ) {
21432156 // No USDT on TON - bridge might have already succeeded!
@@ -2163,20 +2176,21 @@ const executeTacCallbacks = async (context: ProcessingContext): Promise<void> =>
21632176 const minExpectedAmount = calculateMinExpectedAmount ( expectedAmount , slippageDbps ) ;
21642177
21652178 // Validate: Must have at least minimum expected amount
2166- if ( actualUsdtBalance < minExpectedAmount ) {
2179+ if ( actualUsdtBalance18 < minExpectedAmount ) {
21672180 logger . warn ( 'Insufficient USDT on TON for this operation (retry) - waiting' , {
21682181 ...logContext ,
21692182 expectedAmount : expectedAmount . toString ( ) ,
21702183 minExpectedAmount : minExpectedAmount . toString ( ) ,
2171- actualUsdtBalance : actualUsdtBalance . toString ( ) ,
2184+ actualUsdtBalance18 : actualUsdtBalance18 . toString ( ) ,
21722185 note : 'Another flow may have taken funds or Stargate still in transit' ,
21732186 } ) ;
21742187 continue ;
21752188 }
21762189
21772190 // Calculate amount: min(expectedAmount, actualBalance) - never more than expected
2178- const amountToBridgeBigInt = actualUsdtBalance < expectedAmount ? actualUsdtBalance : expectedAmount ;
2179- const amountToBridge = amountToBridgeBigInt . toString ( ) ;
2191+ const amountToBridgeBigInt =
2192+ actualUsdtBalance18 < expectedAmount ? actualUsdtBalance18 : expectedAmount ;
2193+ const amountToBridge = convertToNativeUnits ( amountToBridgeBigInt , tonUSDTDecimals ) . toString ( ) ;
21802194
21812195 logger . info ( 'Retrying TAC SDK bridge execution (no transactionLinker)' , {
21822196 ...logContext ,
0 commit comments