fix: Make all tests pass!

Delete TokenTransfer.sol
Make slither happy

Bugfixes:
- Executors
  - Ekubo:
    - Fix the POOL_DATA_OFFSET value and remove sender from callback data
    - Use SafeERC20
  - Maverick and Univ2: Use safeTransfer and not safeTransferFrom
  - Univ3: update expected data length
  - Univ4: update the selectors (the signature changed)
- Router:
  - For split swap we don't need to pass the tokenInReceiver, it should always be the router address
  - For single and sequential: change order of the parameters (to be before the permit2 specific objects)
- Encoders:
  - Update selector signatures
  - For split swap pass the transfer_from (we might not need to if the token in is ETH)

Took 2 hours 51 minutes
This commit is contained in:
Diana Carvalho
2025-05-15 13:11:34 +01:00
parent 27dfde3118
commit ee687038c5
20 changed files with 126 additions and 197 deletions

View File

@@ -52,11 +52,12 @@ impl SingleSwapStrategyEncoder {
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())
(Some(Permit2::new(swapper_pk, chain.clone())?), "singleSwapPermit2(uint256,address,address,uint256,bool,bool,address,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string())
} else {
(
None,
"singleSwap(uint256,address,address,uint256,bool,bool,address,bytes)".to_string(),
"singleSwap(uint256,address,address,uint256,bool,bool,address,bool,address,bytes)"
.to_string(),
)
};
Ok(Self {
@@ -247,11 +248,11 @@ impl SequentialSwapStrategyEncoder {
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())
(Some(Permit2::new(swapper_pk, chain.clone())?), "sequentialSwapPermit2(uint256,address,address,uint256,bool,bool,address,bool,address,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string())
} else {
(
None,
"sequentialSwap(uint256,address,address,uint256,bool,bool,address,bytes)"
"sequentialSwap(uint256,address,address,uint256,bool,bool,address,bool,address,bytes)"
.to_string(),
)
};
@@ -461,11 +462,11 @@ impl SplitSwapStrategyEncoder {
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())
(Some(Permit2::new(swapper_pk, chain.clone())?), "splitSwapPermit2(uint256,address,address,uint256,bool,bool,uint256,address,bool,((address,uint160,uint48,uint48),address,uint256),bytes,bytes)".to_string())
} else {
(
None,
"splitSwap(uint256,address,address,uint256,bool,bool,uint256,address,bytes)"
"splitSwap(uint256,address,address,uint256,bool,bool,uint256,address,bool,bytes)"
.to_string(),
)
};
@@ -569,6 +570,9 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
tokens.push(solution.checked_token.clone());
}
let (transfer_from, _funds_receiver, _transfer) = self
.transfer_optimization
.get_transfers(grouped_swaps[0].clone(), wrap);
let mut swaps = vec![];
for grouped_swap in grouped_swaps.iter() {
let protocol = grouped_swap.protocol_system.clone();
@@ -639,6 +643,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
unwrap,
U256::from(tokens_len),
bytes_to_address(&solution.receiver)?,
transfer_from,
permit,
signature.as_bytes().to_vec(),
encoded_swaps,
@@ -654,6 +659,7 @@ impl StrategyEncoder for SplitSwapStrategyEncoder {
unwrap,
U256::from(tokens_len),
bytes_to_address(&solution.receiver)?,
transfer_from,
encoded_swaps,
)
.abi_encode()
@@ -782,8 +788,8 @@ mod tests {
.unwrap();
let expected_min_amount_encoded = hex::encode(U256::abi_encode(&expected_min_amount));
let expected_input = [
"30ace1b1", // Function selector
"0000000000000000000000000000000000000000000000000de0b6b3a7640000", // amount out
"a93aabdf", // Function selector
"0000000000000000000000000000000000000000000000000de0b6b3a7640000", // amount in
"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f", // token out
&expected_min_amount_encoded, // min amount out
@@ -874,7 +880,7 @@ mod tests {
.unwrap();
let expected_min_amount_encoded = hex::encode(U256::abi_encode(&expected_min_amount));
let expected_input = [
"20144a07", // Function selector
"cc60c623", // Function selector
"0000000000000000000000000000000000000000000000000de0b6b3a7640000", // amount in
"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f", // token out
@@ -958,7 +964,7 @@ mod tests {
.unwrap();
let expected_min_amount_encoded = hex::encode(U256::abi_encode(&expected_min_amount));
let expected_input = [
"20144a07", // Function selector
"cc60c623", // Function selector
"0000000000000000000000000000000000000000000000000de0b6b3a7640000", // amount in
"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"0000000000000000000000006b175474e89094c44da98b954eedeac495271d0f", // token out
@@ -1230,7 +1236,7 @@ mod tests {
let hex_calldata = encode(&calldata);
let expected = String::from(concat!(
"e8a980d7", /* function selector */
"59e3efbb", /* function selector */
"0000000000000000000000000000000000000000000000000de0b6b3a7640000", // amount in
"000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", // token in
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token ou
@@ -1356,7 +1362,7 @@ mod tests {
.unwrap();
let hex_calldata = hex::encode(&calldata);
let expected_input = [
"51bcc7b6", // selector
"740bae0c", // selector
"0000000000000000000000000000000000000000000000000000000005f5e100", // given amount
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // given token
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // checked token
@@ -2073,7 +2079,7 @@ mod tests {
let hex_calldata = hex::encode(&calldata);
let expected_input = [
"7c553846", // selector
"308f3ce0", // selector
"0000000000000000000000000000000000000000000000000000000005f5e100", // given amount
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // given token
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // checked token
@@ -2082,6 +2088,7 @@ mod tests {
"0000000000000000000000000000000000000000000000000000000000000000", // unwrap action
"0000000000000000000000000000000000000000000000000000000000000002", // tokens length
"000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"0000000000000000000000000000000000000000000000000000000000000001", // transfer from
]
.join("");
let expected_swaps = [
@@ -2125,8 +2132,8 @@ mod tests {
"0000000000" // padding
]
.join("");
assert_eq!(hex_calldata[..520], expected_input);
assert_eq!(hex_calldata[1288..], expected_swaps);
assert_eq!(hex_calldata[..584], expected_input);
assert_eq!(hex_calldata[1352..], expected_swaps);
write_calldata_to_file("test_split_input_cyclic_swap", hex_calldata.as_str());
}
@@ -2238,7 +2245,7 @@ mod tests {
let hex_calldata = hex::encode(&calldata);
let expected_input = [
"7c553846", // selector
"308f3ce0", // selector
"0000000000000000000000000000000000000000000000000000000005f5e100", // given amount
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // given token
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // checked token
@@ -2247,6 +2254,7 @@ mod tests {
"0000000000000000000000000000000000000000000000000000000000000000", // unwrap action
"0000000000000000000000000000000000000000000000000000000000000002", // tokens length
"000000000000000000000000cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
"0000000000000000000000000000000000000000000000000000000000000001", // transfer from
]
.join("");
@@ -2292,8 +2300,8 @@ mod tests {
]
.join("");
assert_eq!(hex_calldata[..520], expected_input);
assert_eq!(hex_calldata[1288..], expected_swaps);
assert_eq!(hex_calldata[..584], expected_input);
assert_eq!(hex_calldata[1352..], expected_swaps);
write_calldata_to_file("test_split_output_cyclic_swap", hex_calldata.as_str());
}
}
@@ -2641,7 +2649,7 @@ mod tests {
.unwrap();
let expected_input = [
"30ace1b1", // Function selector (single swap)
"a93aabdf", // Function selector (single swap)
"000000000000000000000000000000000000000000000000000000003b9aca00", // amount in
"000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // token in
"0000000000000000000000006982508145454ce325ddbe47a25d4ec3d2311933", // token out

View File

@@ -655,7 +655,7 @@ mod tests {
#[test]
fn test_encode_uniswap_v2() {
let usv2_pool = ProtocolComponent {
id: String::from("0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640"),
id: String::from("0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11"),
..Default::default()
};
@@ -668,7 +668,7 @@ mod tests {
split: 0f64,
};
let encoding_context = EncodingContext {
receiver: Bytes::from("0x0000000000000000000000000000000000000001"),
receiver: Bytes::from("0x1D96F2f6BeF1202E4Ce1Ff6Dad0c2CB002861d3e"), // BOB
exact_out: false,
router_address: Some(Bytes::zero(20)),
group_token_in: token_in.clone(),
@@ -692,15 +692,16 @@ mod tests {
// in token
"c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
// component id
"88e6a0c2ddd26feeb64f039a2c41296fcb3f5640",
"a478c2975ab1ea89e8196811f51a7b7ade33eb11",
// receiver
"0000000000000000000000000000000000000001",
"1d96f2f6bef1202e4ce1ff6dad0c2cb002861d3e",
// zero for one
"00",
// transfer true
"01",
))
);
write_calldata_to_file("test_encode_uniswap_v2", hex_swap.as_str());
}
}

View File

@@ -462,7 +462,7 @@ mod tests {
Bytes::from_str("0x3ede3eca2a72b3aecc820e955b36f38437d01395").unwrap()
);
// single swap selector
assert_eq!(&hex::encode(transactions[0].clone().data)[..8], "20144a07");
assert_eq!(&hex::encode(transactions[0].clone().data)[..8], "cc60c623");
}
#[test]
@@ -487,7 +487,7 @@ mod tests {
let transactions = transactions.unwrap();
assert_eq!(transactions.len(), 1);
// single swap selector
assert_eq!(&hex::encode(transactions[0].clone().data)[..8], "20144a07");
assert_eq!(&hex::encode(transactions[0].clone().data)[..8], "cc60c623");
}
#[test]
@@ -534,7 +534,7 @@ mod tests {
assert_eq!(transactions.len(), 1);
assert_eq!(transactions[0].value, eth_amount_in);
// sequential swap selector
assert_eq!(&hex::encode(transactions[0].clone().data)[..8], "e8a980d7");
assert_eq!(&hex::encode(transactions[0].clone().data)[..8], "59e3efbb");
}
#[test]