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:
@@ -21,6 +21,7 @@ pub struct TychoRouterEncoderBuilder {
|
|||||||
chain: Option<Chain>,
|
chain: Option<Chain>,
|
||||||
executors_file_path: Option<String>,
|
executors_file_path: Option<String>,
|
||||||
router_address: Option<Bytes>,
|
router_address: Option<Bytes>,
|
||||||
|
token_in_already_in_router: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TychoRouterEncoderBuilder {
|
impl Default for TychoRouterEncoderBuilder {
|
||||||
@@ -36,6 +37,7 @@ impl TychoRouterEncoderBuilder {
|
|||||||
chain: None,
|
chain: None,
|
||||||
executors_file_path: None,
|
executors_file_path: None,
|
||||||
router_address: None,
|
router_address: None,
|
||||||
|
token_in_already_in_router: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn chain(mut self, chain: TychoCommonChain) -> Self {
|
pub fn chain(mut self, chain: TychoCommonChain) -> Self {
|
||||||
@@ -62,6 +64,16 @@ impl TychoRouterEncoderBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sets the `token_in_already_in_router` flag.
|
||||||
|
// If set to true, the encoder will assume that the token in is already in the router.
|
||||||
|
// WARNING: this is an advanced feature and should be used with caution. Make sure you have
|
||||||
|
// checks to make sure that your tokens won't be lost. The Router is not considered safe to hold
|
||||||
|
// tokens, so if this is not done within the same transaction you will lose your tokens.
|
||||||
|
pub fn token_in_already_in_router(mut self, token_in_already_in_router: bool) -> Self {
|
||||||
|
self.token_in_already_in_router = Some(token_in_already_in_router);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Builds the `TychoRouterEncoder` instance using the configured chain.
|
/// Builds the `TychoRouterEncoder` instance using the configured chain.
|
||||||
/// Returns an error if either the chain has not been set.
|
/// Returns an error if either the chain has not been set.
|
||||||
pub fn build(self) -> Result<Box<dyn TychoEncoder>, EncodingError> {
|
pub fn build(self) -> Result<Box<dyn TychoEncoder>, EncodingError> {
|
||||||
@@ -88,6 +100,8 @@ impl TychoRouterEncoderBuilder {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
self.swapper_pk,
|
self.swapper_pk,
|
||||||
tycho_router_address,
|
tycho_router_address,
|
||||||
|
self.token_in_already_in_router
|
||||||
|
.unwrap_or(false),
|
||||||
)?))
|
)?))
|
||||||
} else {
|
} else {
|
||||||
Err(EncodingError::FatalError(
|
Err(EncodingError::FatalError(
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ impl SingleSwapStrategyEncoder {
|
|||||||
swap_encoder_registry: SwapEncoderRegistry,
|
swap_encoder_registry: SwapEncoderRegistry,
|
||||||
swapper_pk: Option<String>,
|
swapper_pk: Option<String>,
|
||||||
router_address: Bytes,
|
router_address: Bytes,
|
||||||
|
token_in_already_in_router: bool,
|
||||||
) -> Result<Self, EncodingError> {
|
) -> Result<Self, EncodingError> {
|
||||||
let (permit2, selector) = if let Some(swapper_pk) = swapper_pk {
|
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())
|
(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.native_token()?,
|
||||||
chain.wrapped_token()?,
|
chain.wrapped_token()?,
|
||||||
permit2_is_active,
|
permit2_is_active,
|
||||||
|
token_in_already_in_router,
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -228,6 +230,7 @@ impl SequentialSwapStrategyEncoder {
|
|||||||
swap_encoder_registry: SwapEncoderRegistry,
|
swap_encoder_registry: SwapEncoderRegistry,
|
||||||
swapper_pk: Option<String>,
|
swapper_pk: Option<String>,
|
||||||
router_address: Bytes,
|
router_address: Bytes,
|
||||||
|
token_in_already_in_router: bool,
|
||||||
) -> Result<Self, EncodingError> {
|
) -> Result<Self, EncodingError> {
|
||||||
let (permit2, selector) = if let Some(swapper_pk) = swapper_pk {
|
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())
|
(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.native_token()?,
|
||||||
chain.wrapped_token()?,
|
chain.wrapped_token()?,
|
||||||
permit2_is_active,
|
permit2_is_active,
|
||||||
|
token_in_already_in_router,
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -440,6 +444,7 @@ impl SplitSwapStrategyEncoder {
|
|||||||
swap_encoder_registry: SwapEncoderRegistry,
|
swap_encoder_registry: SwapEncoderRegistry,
|
||||||
swapper_pk: Option<String>,
|
swapper_pk: Option<String>,
|
||||||
router_address: Bytes,
|
router_address: Bytes,
|
||||||
|
token_in_already_in_router: bool,
|
||||||
) -> Result<Self, EncodingError> {
|
) -> Result<Self, EncodingError> {
|
||||||
let (permit2, selector) = if let Some(swapper_pk) = swapper_pk {
|
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())
|
(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.native_token()?,
|
||||||
chain.wrapped_token()?,
|
chain.wrapped_token()?,
|
||||||
permit2_is_active,
|
permit2_is_active,
|
||||||
|
token_in_already_in_router,
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -741,6 +747,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -824,6 +831,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -901,6 +909,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -953,6 +962,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -1024,6 +1034,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -1083,6 +1094,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -1201,6 +1213,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -1318,6 +1331,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -1399,6 +1413,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -1484,6 +1499,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -1550,6 +1566,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -1649,6 +1666,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -1758,6 +1776,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key.clone()),
|
Some(private_key.clone()),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -1920,6 +1939,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key.clone()),
|
Some(private_key.clone()),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -2045,6 +2065,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0xA4AD4f68d0b91CFD19687c881e50f3A00242828c").unwrap(),
|
Bytes::from_str("0xA4AD4f68d0b91CFD19687c881e50f3A00242828c").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -2110,6 +2131,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -2178,6 +2200,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -2265,6 +2288,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
Some(private_key),
|
Some(private_key),
|
||||||
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
Bytes::from("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395"),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let solution = Solution {
|
let solution = Solution {
|
||||||
@@ -2367,6 +2391,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@@ -2429,6 +2454,7 @@ mod tests {
|
|||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,17 @@ pub struct TransferOptimization {
|
|||||||
native_token: Bytes,
|
native_token: Bytes,
|
||||||
wrapped_token: Bytes,
|
wrapped_token: Bytes,
|
||||||
permit2: bool,
|
permit2: bool,
|
||||||
|
token_in_already_in_router: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TransferOptimization {
|
impl TransferOptimization {
|
||||||
pub fn new(native_token: Bytes, wrapped_token: Bytes, permit2: bool) -> Self {
|
pub fn new(
|
||||||
TransferOptimization { native_token, wrapped_token, permit2 }
|
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.
|
/// Returns the transfer method that should be used for the given swap and solution.
|
||||||
pub fn get_transfer_type(
|
pub fn get_transfer_type(
|
||||||
@@ -38,19 +44,28 @@ impl TransferOptimization {
|
|||||||
TransferType::TransferToProtocol
|
TransferType::TransferToProtocol
|
||||||
} else if is_first_swap {
|
} else if is_first_swap {
|
||||||
if in_transfer_required {
|
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.
|
// Transfer from swapper to pool using permit2.
|
||||||
TransferType::TransferPermit2ToProtocol
|
TransferType::TransferPermit2ToProtocol
|
||||||
} else {
|
} else {
|
||||||
// Transfer from swapper to pool.
|
// Transfer from swapper to pool.
|
||||||
TransferType::TransferFromToProtocol
|
TransferType::TransferFromToProtocol
|
||||||
}
|
}
|
||||||
} else if self.permit2 {
|
// in transfer is not necessary for these protocols. Only make a transfer if the
|
||||||
// Transfer from swapper to router using permit2.
|
// tokens are not already in the router
|
||||||
TransferType::TransferPermit2ToRouter
|
} 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 {
|
} else {
|
||||||
// Transfer from swapper to router.
|
TransferType::None
|
||||||
TransferType::TransferFromToRouter
|
|
||||||
}
|
}
|
||||||
// all other swaps
|
// all other swaps
|
||||||
} else if !in_transfer_required || in_between_swap_optimization {
|
} else if !in_transfer_required || in_between_swap_optimization {
|
||||||
@@ -65,7 +80,6 @@ impl TransferOptimization {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use alloy_primitives::hex;
|
use alloy_primitives::hex;
|
||||||
use tycho_common::Bytes;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@@ -95,7 +109,7 @@ mod tests {
|
|||||||
split: 0f64,
|
split: 0f64,
|
||||||
swaps: vec![],
|
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);
|
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, false);
|
||||||
assert_eq!(transfer_method, TransferType::TransferPermit2ToProtocol);
|
assert_eq!(transfer_method, TransferType::TransferPermit2ToProtocol);
|
||||||
}
|
}
|
||||||
@@ -110,7 +124,7 @@ mod tests {
|
|||||||
split: 0f64,
|
split: 0f64,
|
||||||
swaps: vec![],
|
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);
|
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, false);
|
||||||
assert_eq!(transfer_method, TransferType::TransferFromToProtocol);
|
assert_eq!(transfer_method, TransferType::TransferFromToProtocol);
|
||||||
}
|
}
|
||||||
@@ -126,7 +140,7 @@ mod tests {
|
|||||||
split: 0f64,
|
split: 0f64,
|
||||||
swaps: vec![],
|
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);
|
let transfer_method = optimization.get_transfer_type(swap.clone(), eth(), false, false);
|
||||||
assert_eq!(transfer_method, TransferType::None);
|
assert_eq!(transfer_method, TransferType::None);
|
||||||
}
|
}
|
||||||
@@ -142,7 +156,7 @@ mod tests {
|
|||||||
split: 0f64,
|
split: 0f64,
|
||||||
swaps: vec![],
|
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);
|
let transfer_method = optimization.get_transfer_type(swap.clone(), eth(), true, false);
|
||||||
assert_eq!(transfer_method, TransferType::TransferToProtocol);
|
assert_eq!(transfer_method, TransferType::TransferToProtocol);
|
||||||
}
|
}
|
||||||
@@ -158,7 +172,7 @@ mod tests {
|
|||||||
split: 0f64,
|
split: 0f64,
|
||||||
swaps: vec![],
|
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);
|
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, false);
|
||||||
assert_eq!(transfer_method, TransferType::TransferToProtocol);
|
assert_eq!(transfer_method, TransferType::TransferToProtocol);
|
||||||
}
|
}
|
||||||
@@ -174,7 +188,7 @@ mod tests {
|
|||||||
split: 0f64,
|
split: 0f64,
|
||||||
swaps: vec![],
|
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);
|
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, false);
|
||||||
assert_eq!(transfer_method, TransferType::None);
|
assert_eq!(transfer_method, TransferType::None);
|
||||||
}
|
}
|
||||||
@@ -190,8 +204,40 @@ mod tests {
|
|||||||
split: 0f64,
|
split: 0f64,
|
||||||
swaps: vec![],
|
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);
|
let transfer_method = optimization.get_transfer_type(swap.clone(), weth(), false, true);
|
||||||
assert_eq!(transfer_method, TransferType::None);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ impl TychoRouterEncoder {
|
|||||||
swap_encoder_registry: SwapEncoderRegistry,
|
swap_encoder_registry: SwapEncoderRegistry,
|
||||||
swapper_pk: Option<String>,
|
swapper_pk: Option<String>,
|
||||||
router_address: Bytes,
|
router_address: Bytes,
|
||||||
|
token_in_already_in_router: bool,
|
||||||
) -> Result<Self, EncodingError> {
|
) -> Result<Self, EncodingError> {
|
||||||
let native_address = chain.native_token()?;
|
let native_address = chain.native_token()?;
|
||||||
let wrapped_address = chain.wrapped_token()?;
|
let wrapped_address = chain.wrapped_token()?;
|
||||||
@@ -48,18 +49,21 @@ impl TychoRouterEncoder {
|
|||||||
swap_encoder_registry.clone(),
|
swap_encoder_registry.clone(),
|
||||||
swapper_pk.clone(),
|
swapper_pk.clone(),
|
||||||
router_address.clone(),
|
router_address.clone(),
|
||||||
|
token_in_already_in_router,
|
||||||
)?,
|
)?,
|
||||||
sequential_swap_strategy: SequentialSwapStrategyEncoder::new(
|
sequential_swap_strategy: SequentialSwapStrategyEncoder::new(
|
||||||
chain.clone(),
|
chain.clone(),
|
||||||
swap_encoder_registry.clone(),
|
swap_encoder_registry.clone(),
|
||||||
swapper_pk.clone(),
|
swapper_pk.clone(),
|
||||||
router_address.clone(),
|
router_address.clone(),
|
||||||
|
token_in_already_in_router,
|
||||||
)?,
|
)?,
|
||||||
split_swap_strategy: SplitSwapStrategyEncoder::new(
|
split_swap_strategy: SplitSwapStrategyEncoder::new(
|
||||||
chain,
|
chain,
|
||||||
swap_encoder_registry,
|
swap_encoder_registry,
|
||||||
None,
|
None,
|
||||||
router_address.clone(),
|
router_address.clone(),
|
||||||
|
token_in_already_in_router,
|
||||||
)?,
|
)?,
|
||||||
native_address,
|
native_address,
|
||||||
wrapped_address,
|
wrapped_address,
|
||||||
@@ -258,8 +262,8 @@ impl TychoExecutorEncoder {
|
|||||||
receiver: receiver.clone(),
|
receiver: receiver.clone(),
|
||||||
exact_out: solution.exact_out,
|
exact_out: solution.exact_out,
|
||||||
router_address: None,
|
router_address: None,
|
||||||
group_token_in: grouped_swap.input_token.clone(),
|
group_token_in: grouped_swap.token_in.clone(),
|
||||||
group_token_out: grouped_swap.output_token.clone(),
|
group_token_out: grouped_swap.token_out.clone(),
|
||||||
transfer_type: TransferType::TransferToProtocol,
|
transfer_type: TransferType::TransferToProtocol,
|
||||||
};
|
};
|
||||||
let protocol_data = swap_encoder.encode_swap(swap.clone(), encoding_context.clone())?;
|
let protocol_data = swap_encoder.encode_swap(swap.clone(), encoding_context.clone())?;
|
||||||
@@ -354,6 +358,7 @@ mod tests {
|
|||||||
get_swap_encoder_registry(),
|
get_swap_encoder_registry(),
|
||||||
None,
|
None,
|
||||||
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
Bytes::from_str("0x3Ede3eCa2a72B3aeCC820E955B36f38437D01395").unwrap(),
|
||||||
|
false,
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user