feat: Allow for token_in_already_in_router
--- don't change below this line --- ENG-4446 Took 31 minutes Took 26 seconds
This commit is contained in:
@@ -49,6 +49,7 @@ impl SingleSwapStrategyEncoder {
|
||||
swap_encoder_registry: SwapEncoderRegistry,
|
||||
swapper_pk: Option<String>,
|
||||
router_address: Bytes,
|
||||
token_in_already_in_router: bool,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let (permit2, selector) = if let Some(swapper_pk) = swapper_pk {
|
||||
(Some(Permit2::new(swapper_pk, chain.clone())?), "singleSwapPermit2(uint256,address,address,uint256,bool,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string())
|
||||
@@ -68,6 +69,7 @@ impl SingleSwapStrategyEncoder {
|
||||
chain.native_token()?,
|
||||
chain.wrapped_token()?,
|
||||
permit2_is_active,
|
||||
token_in_already_in_router,
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -228,6 +230,7 @@ impl SequentialSwapStrategyEncoder {
|
||||
swap_encoder_registry: SwapEncoderRegistry,
|
||||
swapper_pk: Option<String>,
|
||||
router_address: Bytes,
|
||||
token_in_already_in_router: bool,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let (permit2, selector) = if let Some(swapper_pk) = swapper_pk {
|
||||
(Some(Permit2::new(swapper_pk, chain.clone())?), "sequentialSwapPermit2(uint256,address,address,uint256,bool,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string())
|
||||
@@ -251,6 +254,7 @@ impl SequentialSwapStrategyEncoder {
|
||||
chain.native_token()?,
|
||||
chain.wrapped_token()?,
|
||||
permit2_is_active,
|
||||
token_in_already_in_router,
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -440,6 +444,7 @@ impl SplitSwapStrategyEncoder {
|
||||
swap_encoder_registry: SwapEncoderRegistry,
|
||||
swapper_pk: Option<String>,
|
||||
router_address: Bytes,
|
||||
token_in_already_in_router: bool,
|
||||
) -> Result<Self, EncodingError> {
|
||||
let (permit2, selector) = if let Some(swapper_pk) = swapper_pk {
|
||||
(Some(Permit2::new(swapper_pk, chain.clone())?), "splitSwapPermit2(uint256,address,address,uint256,bool,bool,uint256,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string())
|
||||
@@ -463,6 +468,7 @@ impl SplitSwapStrategyEncoder {
|
||||
chain.native_token()?,
|
||||
chain.wrapped_token()?,
|
||||
permit2_is_active,
|
||||
token_in_already_in_router,
|
||||
),
|
||||
})
|
||||
}
|
||||
@@ -741,6 +747,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -824,6 +831,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -901,6 +909,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -953,6 +962,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -1024,6 +1034,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -1083,6 +1094,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -1201,6 +1213,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -1318,6 +1331,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -1399,6 +1413,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -1484,6 +1499,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -1550,6 +1566,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -1649,6 +1666,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -1758,6 +1776,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key.clone()),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -1920,6 +1939,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key.clone()),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -2045,6 +2065,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0xA4AD4f68d0b91CFD19687c881e50f3A00242828c").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -2110,6 +2131,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -2178,6 +2200,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -2265,6 +2288,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
Some(private_key),
|
||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
let solution = Solution {
|
||||
@@ -2367,6 +2391,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -2429,6 +2454,7 @@ mod tests {
|
||||
swap_encoder_registry,
|
||||
None,
|
||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||
false,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -11,11 +11,17 @@ pub struct TransferOptimization {
|
||||
native_token: Bytes,
|
||||
wrapped_token: Bytes,
|
||||
permit2: bool,
|
||||
token_in_already_in_router: bool,
|
||||
}
|
||||
|
||||
impl TransferOptimization {
|
||||
pub fn new(native_token: Bytes, wrapped_token: Bytes, permit2: bool) -> Self {
|
||||
TransferOptimization { native_token, wrapped_token, permit2 }
|
||||
pub fn new(
|
||||
native_token: Bytes,
|
||||
wrapped_token: Bytes,
|
||||
permit2: bool,
|
||||
token_in_already_in_router: bool,
|
||||
) -> Self {
|
||||
TransferOptimization { native_token, wrapped_token, permit2, token_in_already_in_router }
|
||||
}
|
||||
/// Returns the transfer method that should be used for the given swap and solution.
|
||||
pub fn get_transfer_type(
|
||||
@@ -38,19 +44,28 @@ impl TransferOptimization {
|
||||
TransferType::TransferToProtocol
|
||||
} else if is_first_swap {
|
||||
if in_transfer_required {
|
||||
if self.permit2 {
|
||||
if self.token_in_already_in_router {
|
||||
// Transfer from router to pool.
|
||||
TransferType::TransferToProtocol
|
||||
} else if self.permit2 {
|
||||
// Transfer from swapper to pool using permit2.
|
||||
TransferType::TransferPermit2ToProtocol
|
||||
} else {
|
||||
// Transfer from swapper to pool.
|
||||
TransferType::TransferFromToProtocol
|
||||
}
|
||||
} else if self.permit2 {
|
||||
// Transfer from swapper to router using permit2.
|
||||
TransferType::TransferPermit2ToRouter
|
||||
// in transfer is not necessary for these protocols. Only make a transfer if the
|
||||
// tokens are not already in the router
|
||||
} else if !self.token_in_already_in_router {
|
||||
if self.permit2 {
|
||||
// Transfer from swapper to router using permit2.
|
||||
TransferType::TransferPermit2ToRouter
|
||||
} else {
|
||||
// Transfer from swapper to router.
|
||||
TransferType::TransferFromToRouter
|
||||
}
|
||||
} else {
|
||||
// Transfer from swapper to router.
|
||||
TransferType::TransferFromToRouter
|
||||
TransferType::None
|
||||
}
|
||||
// all other swaps
|
||||
} else if !in_transfer_required || in_between_swap_optimization {
|
||||
@@ -65,7 +80,6 @@ impl TransferOptimization {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use alloy_primitives::hex;
|
||||
use tycho_common::Bytes;
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -95,7 +109,7 @@ mod tests {
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), true);
|
||||
let optimization = TransferOptimization::new(eth(), weth(), true, false);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, false);
|
||||
assert_eq!(transfer_method, TransferType::TransferPermit2ToProtocol);
|
||||
}
|
||||
@@ -110,7 +124,7 @@ mod tests {
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false);
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false, false);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, false);
|
||||
assert_eq!(transfer_method, TransferType::TransferFromToProtocol);
|
||||
}
|
||||
@@ -126,7 +140,7 @@ mod tests {
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false);
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false, false);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), eth(), false, false);
|
||||
assert_eq!(transfer_method, TransferType::None);
|
||||
}
|
||||
@@ -142,7 +156,7 @@ mod tests {
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false);
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false, false);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), eth(), true, false);
|
||||
assert_eq!(transfer_method, TransferType::TransferToProtocol);
|
||||
}
|
||||
@@ -158,7 +172,7 @@ mod tests {
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false);
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false, false);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, false);
|
||||
assert_eq!(transfer_method, TransferType::TransferToProtocol);
|
||||
}
|
||||
@@ -174,7 +188,7 @@ mod tests {
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false);
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false, false);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, false);
|
||||
assert_eq!(transfer_method, TransferType::None);
|
||||
}
|
||||
@@ -190,8 +204,40 @@ mod tests {
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false);
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false, false);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, true);
|
||||
assert_eq!(transfer_method, TransferType::None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_first_swap_tokens_already_in_router_optimization() {
|
||||
// It is the first swap, tokens are already in the router and the protocol requires the
|
||||
// transfer in
|
||||
let swap = SwapGroup {
|
||||
protocol_system: "uniswap_v2".to_string(),
|
||||
token_in: usdc(),
|
||||
token_out: dai(),
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false, true);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), usdc(), false, false);
|
||||
assert_eq!(transfer_method, TransferType::TransferToProtocol);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_first_swap_tokens_already_in_router_no_transfer_needed_optimization() {
|
||||
// It is the first swap, tokens are already in the router and the protocol does not require
|
||||
// the transfer in
|
||||
let swap = SwapGroup {
|
||||
protocol_system: "vm:curve".to_string(),
|
||||
token_in: usdc(),
|
||||
token_out: dai(),
|
||||
split: 0f64,
|
||||
swaps: vec![],
|
||||
};
|
||||
let optimization = TransferOptimization::new(eth(), weth(), false, true);
|
||||
let transfer_method = optimization.get_transfer_type(swap.clone(), usdc(), false, false);
|
||||
assert_eq!(transfer_method, TransferType::None);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user