13
13
assets:: { SimulationParams , BRIDGING_ASSETS } ,
14
14
ethers:: { types:: H160 as EthersH160 , utils:: keccak256} ,
15
15
serde:: { Deserialize , Serialize } ,
16
- std:: { collections:: HashMap , str:: FromStr , sync:: Arc } ,
16
+ std:: { cmp :: Ordering , collections:: HashMap , str:: FromStr , sync:: Arc } ,
17
17
tracing:: debug,
18
18
yttrium:: chain_abstraction:: api:: Transaction ,
19
19
} ;
@@ -23,7 +23,7 @@ pub mod route;
23
23
pub mod status;
24
24
25
25
/// How much to multiply the bridging fee amount to cover bridging fee volatility
26
- pub const BRIDGING_FEE_SLIPPAGE : i8 = 75 ; // 75 %
26
+ pub const BRIDGING_FEE_SLIPPAGE : i16 = 200 ; // 200 %
27
27
28
28
/// Bridging timeout in seconds
29
29
pub const BRIDGING_TIMEOUT : u64 = 1800 ; // 30 minutes
@@ -125,6 +125,7 @@ pub struct BridgingAsset {
125
125
/// Checking available assets amount for bridging excluding the initial transaction
126
126
/// asset, prioritizing the asset with the highest balance or the asset with the
127
127
/// same symbol to avoid unnecessary swapping
128
+ #[ allow( clippy:: too_many_arguments) ]
128
129
pub async fn check_bridging_for_erc20_transfer (
129
130
rpc_project_id : String ,
130
131
session_id : Option < String > ,
@@ -135,6 +136,8 @@ pub async fn check_bridging_for_erc20_transfer(
135
136
exclude_contract_address : Address ,
136
137
// Using the same asset as a priority for bridging
137
138
token_symbol_priority : String ,
139
+ // Applying token decimals for the value to compare between different tokens
140
+ amount_token_decimals : u8 ,
138
141
) -> Result < Option < BridgingAsset > , RpcError > {
139
142
// Check ERC20 tokens balance for each of supported assets
140
143
let mut contracts_per_chain: HashMap < ( String , String , u8 ) , Vec < String > > = HashMap :: new ( ) ;
@@ -168,7 +171,8 @@ pub async fn check_bridging_for_erc20_transfer(
168
171
)
169
172
. await ?;
170
173
for ( contract_address, current_balance) in erc20_balances {
171
- if current_balance >= value {
174
+ // Check if the balance compared to the transfer value is enough, applied to the transfer token decimals
175
+ if convert_amount ( current_balance, decimals, amount_token_decimals) >= value {
172
176
// Use the priority asset if found
173
177
if token_symbol == token_symbol_priority {
174
178
return Ok ( Some ( BridgingAsset {
@@ -314,3 +318,49 @@ pub async fn get_assets_changes_from_simulation(
314
318
315
319
Ok ( ( asset_changes, gas_used) )
316
320
}
321
+
322
+ /// Convert the amount between different decimals
323
+ pub fn convert_amount ( amount : U256 , from_decimals : u8 , to_decimals : u8 ) -> U256 {
324
+ match from_decimals. cmp ( & to_decimals) {
325
+ Ordering :: Equal => amount,
326
+ Ordering :: Greater => {
327
+ // Reducing decimals: divide by 10^(from_decimals - to_decimals)
328
+ let diff = from_decimals - to_decimals;
329
+ let exp = U256 :: from ( diff as u64 ) ;
330
+ let factor = U256 :: from ( 10 ) . pow ( exp) ;
331
+ amount / factor
332
+ }
333
+ Ordering :: Less => {
334
+ // Increasing decimals: multiply by 10^(to_decimals - from_decimals)
335
+ let diff = to_decimals - from_decimals;
336
+ let exp = U256 :: from ( diff as u64 ) ;
337
+ let factor = U256 :: from ( 10 ) . pow ( exp) ;
338
+ amount * factor
339
+ }
340
+ }
341
+ }
342
+
343
+ #[ cfg( test) ]
344
+ mod tests {
345
+ use super :: * ;
346
+ use std:: str:: FromStr ;
347
+
348
+ #[ test]
349
+ fn test_convert_amount ( ) {
350
+ let amount = U256 :: from_str ( "12345678901234567890" ) . unwrap ( ) ;
351
+ let converted = convert_amount ( amount, 18 , 18 ) ;
352
+ assert_eq ! ( converted, amount) ;
353
+
354
+ // Converting 500 USDT (6 decimals) to 18 decimals.
355
+ let usdt_amount = U256 :: from ( 500_000_000u64 ) ;
356
+ let converted = convert_amount ( usdt_amount, 6 , 18 ) ;
357
+ let expected = U256 :: from_str ( "500000000000000000000" ) . unwrap ( ) ;
358
+ assert_eq ! ( converted, expected) ;
359
+
360
+ // Converting 500 DAI (18 decimals) to 6 decimals.
361
+ let dai_amount = U256 :: from_str ( "500000000000000000000" ) . unwrap ( ) ;
362
+ let converted = convert_amount ( dai_amount, 18 , 6 ) ;
363
+ let expected = U256 :: from ( 500_000_000u64 ) ;
364
+ assert_eq ! ( converted, expected) ;
365
+ }
366
+ }
0 commit comments