feat: Support using the TransferType in uniswap v4
Update tests --- don't change below this line --- ENG-4437 Took 1 hour 3 minutes Took 2 minutes
This commit is contained in:
@@ -80,18 +80,6 @@ contract UniswapV4Executor is
|
|||||||
address receiver,
|
address receiver,
|
||||||
UniswapV4Executor.UniswapV4Pool[] memory pools
|
UniswapV4Executor.UniswapV4Pool[] memory pools
|
||||||
) = _decodeData(data);
|
) = _decodeData(data);
|
||||||
|
|
||||||
// TODO move this into callback when we implement callback transfer type support
|
|
||||||
_transfer(
|
|
||||||
tokenIn,
|
|
||||||
msg.sender,
|
|
||||||
// Receiver can never be the pool, since the pool expects funds in the router contract
|
|
||||||
// Thus, this call will only ever be used to transfer funds from the user into the router.
|
|
||||||
address(this),
|
|
||||||
amountIn,
|
|
||||||
transferType
|
|
||||||
);
|
|
||||||
|
|
||||||
bytes memory swapData;
|
bytes memory swapData;
|
||||||
if (pools.length == 1) {
|
if (pools.length == 1) {
|
||||||
PoolKey memory key = PoolKey({
|
PoolKey memory key = PoolKey({
|
||||||
@@ -106,6 +94,8 @@ contract UniswapV4Executor is
|
|||||||
key,
|
key,
|
||||||
zeroForOne,
|
zeroForOne,
|
||||||
amountIn,
|
amountIn,
|
||||||
|
msg.sender,
|
||||||
|
transferType,
|
||||||
receiver,
|
receiver,
|
||||||
bytes("")
|
bytes("")
|
||||||
);
|
);
|
||||||
@@ -127,6 +117,8 @@ contract UniswapV4Executor is
|
|||||||
currencyIn,
|
currencyIn,
|
||||||
path,
|
path,
|
||||||
amountIn,
|
amountIn,
|
||||||
|
msg.sender,
|
||||||
|
transferType,
|
||||||
receiver
|
receiver
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -240,6 +232,8 @@ contract UniswapV4Executor is
|
|||||||
* @param poolKey The key of the pool to swap in.
|
* @param poolKey The key of the pool to swap in.
|
||||||
* @param zeroForOne Whether the swap is from token0 to token1 (true) or vice versa (false).
|
* @param zeroForOne Whether the swap is from token0 to token1 (true) or vice versa (false).
|
||||||
* @param amountIn The amount of tokens to swap in.
|
* @param amountIn The amount of tokens to swap in.
|
||||||
|
* @param sender The address of the sender.
|
||||||
|
* @param transferType The type of transfer in to use.
|
||||||
* @param receiver The address of the receiver.
|
* @param receiver The address of the receiver.
|
||||||
* @param hookData Additional data for hook contracts.
|
* @param hookData Additional data for hook contracts.
|
||||||
*/
|
*/
|
||||||
@@ -247,6 +241,8 @@ contract UniswapV4Executor is
|
|||||||
PoolKey memory poolKey,
|
PoolKey memory poolKey,
|
||||||
bool zeroForOne,
|
bool zeroForOne,
|
||||||
uint128 amountIn,
|
uint128 amountIn,
|
||||||
|
address sender,
|
||||||
|
TransferType transferType,
|
||||||
address receiver,
|
address receiver,
|
||||||
bytes calldata hookData
|
bytes calldata hookData
|
||||||
) external returns (uint128) {
|
) external returns (uint128) {
|
||||||
@@ -259,7 +255,7 @@ contract UniswapV4Executor is
|
|||||||
if (amount > amountIn) {
|
if (amount > amountIn) {
|
||||||
revert UniswapV4Executor__V4TooMuchRequested(amountIn, amount);
|
revert UniswapV4Executor__V4TooMuchRequested(amountIn, amount);
|
||||||
}
|
}
|
||||||
_settle(currencyIn, address(this), amount);
|
_settle(currencyIn, amount, sender, transferType);
|
||||||
|
|
||||||
Currency currencyOut =
|
Currency currencyOut =
|
||||||
zeroForOne ? poolKey.currency1 : poolKey.currency0;
|
zeroForOne ? poolKey.currency1 : poolKey.currency0;
|
||||||
@@ -272,12 +268,16 @@ contract UniswapV4Executor is
|
|||||||
* @param currencyIn The currency of the input token.
|
* @param currencyIn The currency of the input token.
|
||||||
* @param path The path to swap along.
|
* @param path The path to swap along.
|
||||||
* @param amountIn The amount of tokens to swap in.
|
* @param amountIn The amount of tokens to swap in.
|
||||||
|
* @param sender The address of the sender.
|
||||||
|
* @param transferType The type of transfer in to use.
|
||||||
* @param receiver The address of the receiver.
|
* @param receiver The address of the receiver.
|
||||||
*/
|
*/
|
||||||
function swapExactInput(
|
function swapExactInput(
|
||||||
Currency currencyIn,
|
Currency currencyIn,
|
||||||
PathKey[] calldata path,
|
PathKey[] calldata path,
|
||||||
uint128 amountIn,
|
uint128 amountIn,
|
||||||
|
address sender,
|
||||||
|
TransferType transferType,
|
||||||
address receiver
|
address receiver
|
||||||
) external returns (uint128) {
|
) external returns (uint128) {
|
||||||
uint128 amountOut = 0;
|
uint128 amountOut = 0;
|
||||||
@@ -308,7 +308,7 @@ contract UniswapV4Executor is
|
|||||||
if (amount > amountIn) {
|
if (amount > amountIn) {
|
||||||
revert UniswapV4Executor__V4TooMuchRequested(amountIn, amount);
|
revert UniswapV4Executor__V4TooMuchRequested(amountIn, amount);
|
||||||
}
|
}
|
||||||
_settle(currencyIn, address(this), amount);
|
_settle(currencyIn, amount, sender, transferType);
|
||||||
|
|
||||||
_take(
|
_take(
|
||||||
swapCurrencyIn, // at the end of the loop this is actually currency out
|
swapCurrencyIn, // at the end of the loop this is actually currency out
|
||||||
@@ -379,32 +379,35 @@ contract UniswapV4Executor is
|
|||||||
* @notice Pays and settles a currency to the pool manager.
|
* @notice Pays and settles a currency to the pool manager.
|
||||||
* @dev The implementing contract must ensure that the `payer` is a secure address.
|
* @dev The implementing contract must ensure that the `payer` is a secure address.
|
||||||
* @param currency The currency to settle.
|
* @param currency The currency to settle.
|
||||||
* @param payer The address of the payer.
|
|
||||||
* @param amount The amount to send.
|
* @param amount The amount to send.
|
||||||
|
* @param sender The address of the payer.
|
||||||
|
* @param transferType The type of transfer to use.
|
||||||
* @dev Returns early if the amount is 0.
|
* @dev Returns early if the amount is 0.
|
||||||
*/
|
*/
|
||||||
function _settle(Currency currency, address payer, uint256 amount)
|
function _settle(
|
||||||
internal
|
Currency currency,
|
||||||
{
|
uint256 amount,
|
||||||
|
address sender,
|
||||||
|
TransferType transferType
|
||||||
|
) internal {
|
||||||
if (amount == 0) return;
|
if (amount == 0) return;
|
||||||
|
|
||||||
poolManager.sync(currency);
|
poolManager.sync(currency);
|
||||||
if (currency.isAddressZero()) {
|
if (currency.isAddressZero()) {
|
||||||
// slither-disable-next-line unused-return
|
// slither-disable-next-line unused-return
|
||||||
poolManager.settle{value: amount}();
|
poolManager.settle{value: amount}();
|
||||||
} else {
|
} else {
|
||||||
_pay(currency, payer, amount);
|
_transfer(
|
||||||
|
Currency.unwrap(currency),
|
||||||
|
sender,
|
||||||
|
address(poolManager),
|
||||||
|
amount,
|
||||||
|
transferType
|
||||||
|
);
|
||||||
// slither-disable-next-line unused-return
|
// slither-disable-next-line unused-return
|
||||||
poolManager.settle();
|
poolManager.settle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _pay(Currency token, address, uint256 amount) internal {
|
|
||||||
IERC20(Currency.unwrap(token)).safeTransfer(
|
|
||||||
address(poolManager), amount
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @notice Takes an amount of currency out of the pool manager.
|
* @notice Takes an amount of currency out of the pool manager.
|
||||||
* @param currency The currency to take.
|
* @param currency The currency to take.
|
||||||
|
|||||||
0
foundry/test/TychoRouterIntegration.t.sol
Normal file
0
foundry/test/TychoRouterIntegration.t.sol
Normal file
@@ -427,7 +427,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
|||||||
USDE_ADDR,
|
USDE_ADDR,
|
||||||
USDT_ADDR,
|
USDT_ADDR,
|
||||||
true,
|
true,
|
||||||
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_ROUTER,
|
TokenTransfer.TransferType.TRANSFER_PERMIT2_TO_PROTOCOL,
|
||||||
ALICE,
|
ALICE,
|
||||||
pools
|
pools
|
||||||
);
|
);
|
||||||
@@ -480,7 +480,7 @@ contract TychoRouterSplitSwapTest is TychoRouterTestSetup {
|
|||||||
USDE_ADDR,
|
USDE_ADDR,
|
||||||
WBTC_ADDR,
|
WBTC_ADDR,
|
||||||
true,
|
true,
|
||||||
TokenTransfer.TransferType.NONE,
|
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL,
|
||||||
ALICE,
|
ALICE,
|
||||||
pools
|
pools
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
|
|||||||
USDE_ADDR,
|
USDE_ADDR,
|
||||||
USDT_ADDR,
|
USDT_ADDR,
|
||||||
true,
|
true,
|
||||||
TokenTransfer.TransferType.NONE,
|
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL,
|
||||||
ALICE,
|
ALICE,
|
||||||
pools
|
pools
|
||||||
);
|
);
|
||||||
@@ -172,7 +172,7 @@ contract UniswapV4ExecutorTest is Test, Constants {
|
|||||||
USDE_ADDR,
|
USDE_ADDR,
|
||||||
WBTC_ADDR,
|
WBTC_ADDR,
|
||||||
true,
|
true,
|
||||||
TokenTransfer.TransferType.NONE,
|
TokenTransfer.TransferType.TRANSFER_TO_PROTOCOL,
|
||||||
ALICE,
|
ALICE,
|
||||||
pools
|
pools
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ pub static IN_TRANSFER_REQUIRED_PROTOCOLS: LazyLock<HashSet<&'static str>> = Laz
|
|||||||
set.insert("pancakeswap_v2");
|
set.insert("pancakeswap_v2");
|
||||||
set.insert("uniswap_v3");
|
set.insert("uniswap_v3");
|
||||||
set.insert("pancakeswap_v3");
|
set.insert("pancakeswap_v3");
|
||||||
|
set.insert("uniswap_v4");
|
||||||
set.insert("ekubo_v2");
|
set.insert("ekubo_v2");
|
||||||
set
|
set
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2314,7 +2314,7 @@ mod tests {
|
|||||||
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // group token in
|
"a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", // group token in
|
||||||
"6982508145454ce325ddbe47a25d4ec3d2311933", // group token in
|
"6982508145454ce325ddbe47a25d4ec3d2311933", // group token in
|
||||||
"00", // zero2one
|
"00", // zero2one
|
||||||
"04", // transfer type (transfer to router)
|
"02", // transfer type (transfer to router)
|
||||||
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
|
"cd09f75e2bf2a4d11f3ab23f1389fcc1621c0cc2", // receiver
|
||||||
// First pool params
|
// First pool params
|
||||||
"0000000000000000000000000000000000000000", // intermediary token (ETH)
|
"0000000000000000000000000000000000000000", // intermediary token (ETH)
|
||||||
|
|||||||
Reference in New Issue
Block a user